Il viaggio di Driftrock verso la consegna continua

31 marzo 2017

Nel corso dell'ultimo anno, Driftrock ha intrapreso un percorso piuttosto tipico, che forse avrete già sentito: siamo passati da implementazioni manuali e dall'apatia per la spedizione del software a implementazioni automatizzate e ripetibili, con l'obiettivo di fornire valore.

Piuttosto che annoiarvi con l'ennesimo post sui meriti della Continuous Delivery, anche se mi piacerebbe, cercherò invece di concentrarmi su come abbiamo realizzato questo cambiamento. Ispirandomi al libro More Fearless Change di Mary Lynn Manns e Linda Rising, farò del mio meglio per ricordare i passi che abbiamo fatto e, più in particolare, i modelli che continuiamo a usare per cercare di cambiare i comportamenti del team.

Arretrare l'anno (o gli anni)

Prima di tutto un po' di contesto: nel giugno 2016 una modifica a una qualsiasi delle nostre applicazioni si faceva strada verso la produzione. C'era pochissima consapevolezza del fatto che una modifica fosse stata distribuita, c'era un modello di ramificazione frustrante e popolare che aumentava drasticamente il carico cognitivo e le distribuzioni venivano attivate manualmente dalla macchina di uno sviluppatore tramite la CLI di Heroku.

Un nuovo cambiamento dallo sviluppo alla produzione si presentava più o meno così:

Verde - passo automatizzato. Arancione - passaggio manuale inevitabile o un passaggio manuale che non vogliamo (ancora) cambiare. Rosso - passaggio manuale evitabile.

Verde - passo automatizzato.
Arancione - passo manuale inevitabile o passo manuale che non vogliamo (ancora) cambiare.
Rosso - passo manuale evitabile.

C'era anche una serie di incoerenze nel processo di distribuzione a seconda dell'applicazione. Alcune non avevano un ambiente di staging, quelle che ce l'avevano potevano o meno essere distribuite automaticamente in staging e non tutte le applicazioni avevano test automatizzati eseguiti su master o su altri rami. In breve, era inutilmente complesso, selvaggiamente incoerente e poco o per nulla automatizzato. Non c'è quindi da stupirsi che il team non fosse interessato a distribuire il software.

Tutto ciò significava che le distribuzioni erano irregolari e rischiose. Il più delle volte un grande lotto di modifiche veniva inviato in diretta, aumentando prevedibilmente la probabilità che qualcosa andasse storto e talvolta eliminando la possibilità di effettuare un rollback in sicurezza.

Passi di bimbo

Cercherò di spiegare i passi che abbiamo fatto e i modelli rilevanti che abbiamo usato per migliorare lo scenario descritto sopra. In fondo a questa pagina c'è un riferimento per i modelli citati in questi passaggi. Inoltre, potete trovare tutti i pattern comodamente elencati e descritti qui.

Passo 1 - Coinvolgere tutti

In modo non convenzionale, è iniziato migliorando le nostre retrospettive. Il team aveva bisogno di una piattaforma per discutere i problemi e suggerire miglioramenti(coinvolgere tutti). Sebbene avessimo una chat settimanale chiamata retrospettiva, questa assomigliava poco alle retrospettive che avevo visto in diverse altre aziende. In origine questa riunione era molto più vicina a un aggiornamento settimanale sullo stato di avanzamento, si concentrava sulle attività quotidiane e sui loro progressi piuttosto che su come migliorare il nostro modo di lavorare. Suggerire e poi dimostrare un approccio più strutturato alle retrospettive (facilitando le prime) ha avuto un impatto significativo sul team al di là della Continuous Delivery, ma uno dei primi punti di discussione è stato il modo in cui distribuiamo il nostro software(Plant the Seeds).

Fase 2 - Fallo e basta

Con il team un po' incerto su come il passaggio alla Continuous Delivery potesse essere vantaggioso, il passo successivo è stato semplice: mostrare loro un esempio(Just Do It). Ho creato una semplice applicazione API HTTP con un endpoint che restituisce '200 OK' e ho creato una pipeline di distribuzione in Snap CI. Ho cercato di imitare il modo in cui potremmo trattare le nostre applicazioni normali e ho affrontato solo i problemi più immediati(Scegli le tue battaglie): le distribuzioni manuali e la gestione di più rami in fase di deploy. Quest'ultimo riduce anche la distanza tra lo sviluppo locale e la produzione. Dimostrando che il nostro processo di distribuzione potrebbe iniziare a evolversi in questo senso:

processo di distribuzione-dopo.png

Come ci si può aspettare (come nel caso di un software funzionante), questo è diventato un ottimo punto di riferimento per dimostrare e spiegare il valore del CD e il suo confronto con quello che stavamo facendo.

Fase 3 - Esecuzione di prova

Con quel seme piantato, un esempio funzionante e problemi regolari nella consegna di software di qualità (che evidenziavano solo la gravità del problema), il consenso da parte del resto del team è aumentato costantemente. Il passo successivo è stato quello di impegnare il team a spostare una o due applicazioni reali sul nuovo sistema(Trial Run). Abbiamo preso due applicazioni problematiche per convalidare le nostre ipotesi il prima possibile, abbiamo creato pipeline di distribuzione per loro, le abbiamo distribuite con successo e abbiamo lasciato che il cambiamento si stabilizzasse. A questo punto, fortunatamente, ho avuto un po' di aiuto(Ask for Help), che ha reso i progressi molto più rapidi e il potenziale contraccolpo più facile da gestire.

Fase 4 - PR persistenti

Un modello menzionato nel libro si è imposto alla mia attenzione durante questo processo: le PR persistenti. Riflettendoci, questo modello è apparso sottilmente in diversi luoghi, a volte intenzionalmente, ma spesso involontariamente. Ecco una suddivisione dei punti in cui è apparso:

  • Abbiamo modificato la nostra riunione periodica in modo che si concentrasse prima su ciò che è stato distribuito in produzione, poi sullo staging e infine sullo sviluppo attivo - tipicamente noto come Walk the Board. Anche se indiretto, questo metodo ricorda regolarmente al team di concentrarsi innanzitutto sulla distribuzione del software e su come far avanzare i lavori in produzione.
  • In occasione di una riunione aziendale settimanale, abbiamo mostrato brevemente come abbiamo cambiato il nostro approccio alla distribuzione del software. Per inciso, questo è avvenuto per caso, ma è stata un'opportunità che valeva la pena di cogliere(profumo di successo).
  • Abbiamo iniziato ad acquisire e comunicare le metriche relative al numero di implementazioni in produzione.
  • Abbiamo introdotto alcuni cicli di feedback per favorire il flusso di informazioni sulle implementazioni:
  • Notifiche su Slack: informazioni sui build falliti o sui deployment riusciti. In questo modo gli sviluppatori non hanno dovuto cercare lo stato delle loro modifiche, ma lo hanno ricevuto.
  • Note di rilascio: abbiamo iniziato ad annunciare internamente le modifiche rivolte ai clienti man mano che venivano introdotte. Questo ha contribuito a generare interesse e discussioni sulle nuove funzionalità da parte di tutti i dipendenti dell'azienda.
  • Monitoraggio - un aspetto che non abbiamo ancora risolto completamente, ma continuiamo a sperimentare il monitoraggio e modi migliori per raccogliere feedback dai nostri sistemi di produzione.

Quindi, a che punto siamo?

Attualmente effettuiamo il deploy in produzione circa 15 volte a settimana, un ritmo sostenibile per il nostro team. Abbiamo finito per spostare circa 30 progetti su Snap CI. Abbiamo creato pipeline CD per diverse applicazioni: gemme Ruby, pacchetti Elixir, siti statici ospitati su AWS, applicazioni web su Heroku e altre ospitate su Kubernetes. Tutti i membri del team si assumono la responsabilità di garantire che una modifica a cui stanno lavorando venga distribuita in produzione e lavorano a stretto contatto con gli altri membri del team per testare le funzionalità pertinenti. Ci affidiamo sempre di più ai test automatizzati, ai toggle delle funzionalità e alla retrocompatibilità, argomenti che sono stati ampiamente trattati nelle nostre retrospettive.

Come nota a margine, Snap CI non è stato all'altezza delle aspettative, ma anche questo ha generato alcuni aspetti positivi. Dopo aver riscontrato diversi problemi, abbiamo iniziato a investire nell'uso di Docker per il CI per isolare e assumere la proprietà dell'ambiente di compilazione. Questo ha avuto molti effetti a catena, come l'utilizzo di Docker nello sviluppo e la transizione verso Kubernetes. Inoltre, ha ridotto la nostra dipendenza dallo strumento CI/CD scelto, che è diventato molto importante quando Snap CI ha annunciato la sua scomparsa. Fortunatamente, ora siamo in una posizione migliore per capire di cosa abbiamo bisogno, quindi stiamo per passare a Buildkite(un altro articolo per un'altra volta!).

Speriamo di avervi dato un'idea di come continuiamo la transizione verso la Continuous Delivery e dei modelli che ci hanno aiutato. Il nostro approccio continua a evolversi man mano che impariamo e riconosciamo che abbiamo ancora un po' di strada da fare. Riassumere tutti gli sforzi in quattro fasi è certamente eccessivo: per arrivare al punto in cui siamo ora ci sono voluti molti mesi anche per il nostro piccolo team. Questo viaggio ci ha ricordato che un cambiamento come questo non avviene da un giorno all'altro e che ci vogliono molti piccoli passi nella giusta direzione.

Altre risorse utili

Linda Rising - Miti e modelli del cambiamento organizzativo
Consegna continua - Jez Humble & Dave Farley
Consegna continua - Passare dagli stracci alla ricchezza - Hibri Marzook
Sviluppo basato sul tronco

Modifica dei modelli di riferimento

Parafrasando leggermente il libro, ecco una selezione dei modelli che ho citato sopra:

Piccoli passi - Fate un piccolo passo alla volta verso il vostro obiettivo.
Coinvolgete tutti - Ognuno dovrebbe avere l'opportunità di dare il proprio contributo.
Piantate i semi - Cogliete tutte le occasioni possibili per suscitare interesse in un'idea.
Fatelo e basta - Non aspettate il momento perfetto, ma fate il primo piccolo passo e iniziate a imparare.
Scegliete le vostre battaglie - Concentrate i vostri sforzi sulle questioni più urgenti.
Prova - Quando c'è riluttanza a impegnarsi in un'idea, proponete un esperimento per un breve periodo.
Sveglia - Mettete in evidenza i problemi che creano la necessità di un cambiamento.
Chiedete aiuto - Cercate persone e risorse per aiutare i vostri sforzi e incoraggiate il coinvolgimento.
Pubbliche relazioni persistenti - Mantenete la nuova idea davanti a tutti, promuovendola costantemente in vari modi.
Profumo di successo - Quando i vostri sforzi producono un risultato positivo visibile, consideratelo un momento di insegnamento.