Il conto che nessuno teneva
La call durò quaranta minuti, e la frase che conta arrivò al trentacinquesimo.
«Il nostro Keycloak ce l’abbiamo già. Gli utenti li gestiamo noi, il vostro sistema deve solo fidarsi.»
Il commerciale rispose come rispondono i commerciali quando la richiesta è ragionevole e il contratto è grosso: «certo, si può fare». Aveva ragione. Si poteva fare, si era già fatto altrove, e la stima buttata lì quel giorno (due giorni-uomo) era anche corretta, per la prima volta.
Mesi dopo mi trovai a fare un conto che nessuno aveva mai fatto: quante versioni diverse di quel prodotto erano vive, in quel momento, presso i clienti che l’avevano comprato.
Il conto si ferma intorno alla decina, e già così è più di quanto chiunque si aspettasse. Ma il numero da solo dice poco: quelle configurazioni mettono in gioco una tredicina di servizi diversi, in combinazioni che vanno da due a tutti. Non è una domanda con una risposta ovvia, perché le configurazioni non si sommano. Si moltiplicano. Una struttura porta le proprie utenze dal proprio Keycloak, un altro le lascia gestire al prodotto. Un sede ha la rete isolata verso l’esterno, un altro no. Qui i laboratori sono tre sulla stessa installazione, là uno solo. Ogni scelta è indipendente dalle altre, e ogni combinazione è una cosa che deve funzionare.
Nessuna di queste varianti era stata decisa da un architetto. Erano state tutte concesse in trattativa, una alla volta, ognuna in un momento in cui dire di sì costava meno che dire di no.
E c’è un dettaglio che cambia la natura del problema: chi installa non è uno sviluppatore. In azienda c’è una decina di persone che scrivono codice, e nessuna segue solo quel prodotto. Ma accanto a loro ci sono figure il cui mestiere è preparare l’ambiente per il cliente (background vario, non informatico) che si trovavano davanti a errori che non erano in grado di interpretare. Ogni configurazione in più non era solo una riga di manutenzione: era una situazione nuova in cui qualcuno poteva restare bloccato senza saper dire perché.
Il momento in cui la cosa ha smesso di essere un fastidio interno ha una data e un nome: una brutta figura davanti a un cliente. L’installazione non era verificata come credevamo, e la messa in servizio è diventata un rimpallo: chiedi una verifica, aspetti, ne chiedi un’altra, aspetti ancora. È costato tempo, ma soprattutto è costato la faccia di un’azienda che quel prodotto lo vende.
Fino a quel giorno il costo delle configurazioni era distribuito e invisibile. Da quel giorno aveva un volto.
Ogni rilascio richiedeva prove manuali su ambienti che nessuno sapeva elencare. Un guasto compariva presso un cliente solo e non era riproducibile altrove. Una persona sapeva «come si fa da quel cliente» e senza di lei ci si fermava. Nessuno rispondeva in trattativa senza chiedere prima a uno sviluppatore. Era tutto vero, e nessuna di queste cose era scritta da nessuna parte.
La suite verde che non c’entrava
La prima reazione, quando conti quel numero, è cercare i test.
I test c’erano, ed erano verdi. Migliaia di asserzioni sul prodotto, scritte bene, mantenute nel tempo. Non servivano a niente per questo problema, e ci volle un po’ per accettarlo.
Il motivo è che l’applicazione è la stessa ovunque. Lo stesso identico codice gira dentro tutte quelle sedi. Non è lì che si rompe qualcosa: si rompe nel modo in cui quel codice viene messo in piedi. Una struttura ruota il certificato di firma del proprio Keycloak e le utenze smettono di arrivare; un altro rinnova la rete e un modulo non raggiunge più il servizio che gli serve. In entrambi i casi la suite del prodotto resta verde, perché il prodotto non ha nulla che non va.
L’oggetto da verificare non era il software. Era l’installazione, con la sua configurazione, dentro il suo ambiente.
Questo sposta il problema in un posto scomodo. Un test sul prodotto lo lanci sulla tua macchina. Un test sull’installazione ha bisogno di un’installazione, e le installazioni vivono dentro le sedi dei clienti dove non entri quando ti pare, e in alcuni casi non entri affatto.
Una fonte, due esecutori
La forma che ha retto è più semplice di quanto sembri.
Un solo file YAML elenca le configurazioni supportate. È un elenco, non codice. Per ogni riga, quali moduli ci sono, come arrivano le utenze, cosa deve rispondere e a che livello.
Quel file viene letto da due esecutori diversi. Il primo è uno smoke test in shell che non installa niente: serve dove non puoi installare, ambienti chiusi, macchine di qualcun altro, situazioni in cui hai il permesso di guardare e non di toccare. Il secondo è una suite pytest che porta su l’ambiente con Ansible, da zero, e poi guarda cosa succede.
La parte che conta è che leggono la stessa fonte. Due elenchi separati, uno per esecutore, sarebbero stati più semplici da scrivere e avrebbero divergito nel giro di qualche mese senza che nessuno se ne accorgesse, perché due elenchi che divergono non producono nessun errore, producono due verdi.
Il rosso che aveva torto
Poi arrivò il rosso.
Una configurazione falliva. Non a intermittenza, sempre. Passai quaranta minuti sui log a cercare quale pezzo dell’installazione fosse rotto, con quella sensazione crescente che qualcosa non tornasse, perché era una configurazione vecchia, in esercizio da anni, senza una sola segnalazione dal campo.
Alla fine entrai a mano. Aprii il sistema, feci le cose che il controllo diceva di fare, e le vidi funzionare tutte.
L’installazione era sana. Sbagliava il file che avevo scritto io per dire quando è sana. Descriveva un esito che quel sistema, in quella configurazione, non produceva e non aveva mai prodotto.
È un momento istruttivo, e non per il bug. Per quaranta minuti avevo dato per scontato che l’oracolo avesse ragione e la realtà torto. È lo stesso riflesso per cui una suite verde rassicura: si finisce per fidarsi dello strumento invece che della cosa che lo strumento dovrebbe misurare. Ci ero già passato con una suite che mi mentiva sulla propria copertura, e non l’avevo riconosciuto.
La scoperta peggiore
Se un controllo può sbagliare dicendo rosso a un sistema sano, può sbagliare anche nell’altra direzione. Andai a rileggerli tutti.
Uno controllava il flusso di autenticazione OIDC e accettava come successo qualunque risposta sotto il 500. Un 401 passava per verde. Un 403 passava per verde. In quella configurazione il controllo aveva risposto verde per mesi senza aver mai verificato un accesso riuscito, e stampava a schermo un esito che non corrispondeva a quello che aveva davvero misurato.
E c’era il secondo pezzo, peggiore del primo perché più banale: diverse configurazioni avevano la casella dei controlli semplicemente vuota. Nessun controllo scritto. Nel cruscotto non comparivano come mancanti: non comparivano affatto.
Sommate le due cose, la matrice mostrava una fila di verdi che significavano tre cose diverse: questa funziona, questa non è stata guardata bene, questa non è stata guardata per niente. Tutte disegnate uguali.
È la stessa domanda che mi ero già fatto quando i test hanno cominciato a scriverli gli agenti: chi controlla che funzionino davvero? Qui non li aveva scritti un modello, li avevo scritti io, e il risultato era identico. Un controllo che nessuno verifica è un controllo di cui non sai niente, a prescindere da chi tiene la penna.
La mappa dei buchi
La riparazione non è stata scrivere i controlli mancanti. È stata dichiarare cosa significa verde.
Tre livelli, scritti esplicitamente. Esiste: il container è su, la porta risponde. Risponde: l’endpoint restituisce qualcosa di sensato. Funziona davvero: un login OIDC completo arriva fino al token, con un esito che solo un successo autentico può produrre. Per ogni configurazione si scrive quale livello raggiunge, e le caselle non raggiunte restano bianche.
Il risultato non è un cruscotto tutto verde. È una griglia in cui il bianco si vede, e si vede soprattutto nella terza colonna.
I numeri, quando la griglia è stata compilata per la prima volta: quasi la metà delle configurazioni restava fuori dal giro automatico, testabile solo chiedendolo esplicitamente, cosa che nessuno faceva. Sempre quasi la metà non aveva alcun controllo sul flusso applicativo, e per un paio il controllo si riduceva a verificare che i container fossero accesi.
Il prodotto utile di questo lavoro non è la copertura: è la mappa dei buchi. Una percentuale sarebbe stata più comoda da mostrare e inutile da usare, perché non dice quale configurazione è scoperta, e le configurazioni non sono intercambiabili. Sapere che sei coperto al settanta per cento non serve a nessuno se il trenta scoperto è quello del cliente più grosso.
| Esiste | Risponde | Funziona | |
|---|---|---|---|
| Installazione di riferimento Tutti i moduli, utenze gestite dal prodotto | |||
| Cliente con Keycloak proprio Le utenze arrivano dal sistema dell'cliente | |||
| Sede con rete isolata Nessuna uscita verso l'esterno | |||
| Installazione multi-laboratorio Più laboratori sulla stessa istanza | |||
| Ambiente di collaudo del cliente Dati finti, moduli parziali |
La prima riga è quella su cui si lavora tutti i giorni, ed è l'unica coperta fino in fondo. Le altre esistono in produzione da anni. La colonna che conta è la terza, dove il bianco è quasi tutto.
Chi può fare il lavoro, adesso
Il primo effetto è stato su chi può fare il lavoro.
Con le configurazioni scritte e i controlli dichiarati, non serve più ricordarsi se un caso è nuovo o già visto: si guarda. E persone con meno anzianità hanno cominciato a gestire installazioni che prima richiedevano qualcuno che «se le ricordava»: comprese quelle figure non tecniche il cui mestiere è preparare l’ambiente, che davanti a un errore adesso hanno un posto dove cercare.
La conoscenza ha smesso di stare nelle teste. È il cambiamento che un estraneo avrebbe potuto vedere entrando in azienda, e l’unico che continua a valere anche se domani nessuno tocca più quella matrice.
Il conto torna al commerciale
A questo punto la matrice ha smesso di essere un documento tecnico.
Ogni riga è una configurazione che qualcuno deve tenere viva: quando esce una versione va provata su quella riga, quando cambia una dipendenza va ricontrollata su quella riga, e quando il cliente rinnova qualcosa dalla sua parte è su quella riga che si rompe. Ha un costo mensile, e quel costo esisteva già da anni. Semplicemente non era scritto da nessuna parte, e quello che non è scritto non entra in nessun preventivo.
Il costo di tenerla in piedi è misurabile e non è spaventoso: circa un migliaio di righe fra il file dichiarativo, i due esecutori e i loro test. È una cifra che vale la pena dire a chi teme che mettere ordine costi più del disordine.
La matrice è il listino vero. Non quello dei moduli: quello delle combinazioni.
E cambia la domanda che si fa al tavolo della trattativa. Non più «si può fare?», che ha quasi sempre risposta sì. Ma: quale riga stiamo aggiungendo, e chi la mantiene?
La riga che non abbiamo aggiunto
L’ultima richiesta arrivò quando la matrice esisteva già.
Era ragionevole quanto le altre, tecnicamente fattibile in pochi giorni, e chiedeva una combinazione nuova che nessun’altra installazione aveva. Con la griglia sul tavolo, però, la conversazione fu diversa: non si discusse se si potesse fare, ma quanto sarebbe costato tenerla in piedi per la durata del contratto, e chi l’avrebbe provata a ogni rilascio.
La risposta al cliente non fu no. Fu che quella combinazione si poteva avere accostandola a una riga che esisteva già, rinunciando a un dettaglio che nella pratica non gli cambiava la giornata. Il cliente accettò senza pensarci troppo: era un dettaglio, per l’appunto. Nessuno l’aveva mai potuto proporre prima, perché prima nessuno sapeva che l’alternativa costava una riga in più per sempre.
E questa non è rimasta una volta sola. È diventato il modo di lavorare: davanti a una richiesta si guarda se ricade in qualcosa che esiste già, o se ci si può far ricadere adattandola. È smettere di dire sì per riflesso, che non è dire di no ed è una cosa diversa e molto più difendibile al tavolo.
La frase che riassume tutto non l’ha detta un cliente: è uscita in una revisione interna, dal team che quel prodotto lo installa.
«Sembrava che un’installazione per un cliente nuovo fosse un progetto a sé stante, invece di dare un comando ed eseguire un applicativo, come ci si aspetterebbe.»
Ogni flessibilità concessa in trattativa è una riga di manutenzione che qualcuno pagherà ogni mese, e finché non la scrivi da qualche parte, quel qualcuno non lo sa nessuno.
Il caso è reale, il settore no: dominio, ruoli e terminologia sono stati sostituiti. Tempi e scene sono compressi, e le configurazioni mostrate nella figura sono inventate. Restano fedeli l’esistenza di una fonte dichiarativa unica letta da due esecutori diversi, le configurazioni prive di controlli che passavano lo stesso, e il controllo che accettava risposte di errore come successo dichiarando un esito che non corrispondeva.