Infrastruttura come codice: come Abbiamo rinnovato il nostro processo di sviluppo / rilascio per abbracciare la scala del nostro team

Pubblicato il

(11 dicembre 2020)

In questo articolo, mostriamo come abbiamo gestito il nostro processo di distribuzione continua in passato, cosa ci ha spinto a cambiare ciò che abbiamo, e quali sforzi abbiamo fatto per rendere il processo il più semplice / efficace possibile.

Larticolo può dare un assaggio iniziale di devops, ma nella sua essenza, il processo di rilascio influisce su tutti i team e su come funzionano da soli o collaborare con altri team, mostreremo come i ruoli vengono spostati semplicemente cambiando il processo.

Chi siamo

Noi di Halan aiutiamo a offrire soluzioni logistiche di ride-hailing e on demand ( rate, consegna, pagamenti online, E-commerce) per la popolazione sottoservita dalle tecnologie esistenti nei trasporti e altri servizi, puoi controllare il nostro ap p qui ( android / iOS )

dando il vecchio processo è dovuto, il bene e il male

Inizieremo dal modo in cui abbiamo gestito il nostro processo in passato e da come ciò ci ha influenzato positivamente o negativamente.

Per il mio team, abbiamo quasi tutto viene distribuito su AWS con GitHub come sistema di controllo della versione, quindi dobbiamo trovare un modo per distribuire le funzionalità dai nostri repository GitHub ai servizi AWS.

Distribuzioni di controllo della versione

Noi basato su pipeline di codice AWS , abbiamo impostato i trigger per avviare una pipeline di distribuzione ogni volta che un nuovo commit viene unito a uno dei rami principali che rappresentano le fasi note: dev , prod e staging ambienti.

panoramica su come vengono attivate le distribuzioni

Questo flusso significa che qualsiasi funzione sul ramo principale è in produzione, che sicuramente rende lunione per padroneggiare un argomento tabù da discutere e non tutti avevano che autorizzazione per unire il tuo PR sul master.

La stessa cosa era per gli altri rami, ma non lo era ” Non è davvero un problema, dal momento che dev e staging env non sono poi così spaventosi.

Il nostro QC ha iniziato a testare e verificare le funzionalità quando vengono unite nello staging, il che significa che testano prima su staging env poi se verificato , la funzione verrà unita al ramo master . sembra funzionare bene, ma diamo unocchiata agli aspetti negativi di tale processo.

Questo ci ha permesso di testare e distribuire più funzionalità contemporaneamente in ogni fase (sviluppo, staging), il che è positivo e negativo lo stesso tempo perché:

  • Ciò significa che gli sviluppatori non devono aspettare lun laltro per ottenere il controllo sullambiente di sviluppo / staging.
  • Ma significa che le funzionalità su La fase di sviluppo potrebbe erroneamente causare il non funzionamento o funzionano (falso positivo) ed entrambi i casi sono davvero pessimi e potrebbero fa sì che il codice vada in produzione mentre non funziona.

Rami divergenti, rebase non necessario

Come forse avrai già notato, abbiamo detto che per eseguire il deploy su dev env, devi unire il tuo codice nel ramo dev. Bene, quella parte purtroppo ha rapidamente incasinato la sequenza temporale del nostro ramo poiché:

  • Non tutte le funzionalità che sono state testate su dev entrano in produzione, quindi abbiamo avuto commit fantasma nel nostro ramo di sviluppo unificato .
  • Un laboratorio di sperimentazione senza dubbio, le persone potrebbero scoprire di aver fatto qualcosa di sbagliato dopo un po e decidere di abbandonare il loro codice / commit e iniziarne uno nuovo, ma questo ci lascia ancora con i loro vecchi commit fusa nel ramo dev.

Questo tipo di comportamento ha prodotto quella che chiamiamo divergenza tra rami, per unire una funzione branch che ha master come base in dev, devi risolvere conflitti ! il che è stranamente strano che tu sia letteralmente in conflitto con i fantasmi e risolva cose che non saranno più in produzione , questo sicuramente ti dà due povere opzioni:

  • Costruisci un nuovo ramo per la tua caratteristica biforcuta dal tuo ramo originale della caratteristica e risolvi i conflitti su di esso, quindi, una volta terminato il test, unisci il ramo originale nel master.
  • Risolvi i conflitti sul tuo ramo, quindi scegli i tuoi commit in un nuovo ramo quando ti unisci al master.

Con più sviluppatori che si uniscono al nostro team, le cose inizieranno a diventare più brutte e la divergenza aumenterà sicuramente.

Rinnovare il processo di creazione / distribuzione

La prima cosa che avevamo in mente era come sbarazzarci di quei rami divergenti, abbiamo bisogno di un nuovo metodo per fornire in modo sicuro le funzionalità alla produzione senza interruzioni e controllare quante funzionalità vengono distribuite nella produzione senza coinvolgere il controllo del codice sorgente con lattività di distribuzione.

Una piccola recensione su AWS

Innanzitutto dobbiamo identificare le principali elementi che avranno un ruolo con noi nel processo:

  • Github : controllo del codice sorgente avere repository per ogni micro-servizio disponibile.
  • Amazon ECR : un registro di immagini Docker che è diviso in “repos”, ogni repo rappresenta anche un micro-servizio e contiene le immagini che sono state inviate per il servizio X e possono essere utilizzate o distribuite direttamente a questo servizio per farlo funzionare.
  • Amazon ECS / EC2 / EKS : qui è dove vivono i nostri micro-servizi, insieme ai loro ambienti, ECS è diviso in cluster, ogni cluster contiene un numero di servizi ognuno ha una definizione di attività che contiene informazioni come variabili di ambiente , specifiche di calcolo, rete, ecc.

Quindi dobbiamo trovare un modo per unirli insieme per rendere più facile per noi come team di sviluppo fornire funzionalità e per il controllo qualità controllarle e verificarle caratteristiche.

Abbiamo pensato di poter definire un servizio di intermediazione, un servizio responsabile di distribuzione di altri servizi. Avevamo due comandi principali che volevamo che questo servizio gestisse:

  • Comando build: noi vogliamo essere in grado di creare unimmagine e inviarla a ECR da qualsiasi ramo / commit che vogliamo da un determinato repository GitHub a un determinato repository ECR.
  • Distribuisci comando: vogliamo essere in grado di distribuire una determinata immagine da un repository su ECR a tutti i cluster che contengono il servizio X.

Prendiamo ciascuno di questi comandi al microscopio e vedere cosa comporta ciascuno di essi, iniziamo con il comando Build :

  • Prima di tutto, dobbiamo clonare il repository nel commit / branch specificato.
  • Crea unimmagine docker utilizzando il Dockerfile in quel repository.
  • Esegui il push del immagine creata nel repository ECR con un nuovo tag se necessario o più recente.

Anche se tutti questi passaggi sono certamente doab le nel nostro nuovo servizio di distribuzione, ma abbiamo riscontrato che è complicato da quando la creazione di docker immagini consuma molte immagini risorse e questo limiterà il nostro nuovo servizio a poche simultanee o renderlo così gigantesco in termini di risorse.

Abbiamo pensato che avremmo potuto invece di fare tutto questo lavoro sul servizio stesso, avremmo potuto avviare un nuovo flusso di lavoro su Github su quel repository e passare a tutto dettagli dellattività, come il ramo da controllare e il repository ECR a cui inviare il push, quando è finalmente finito, segnalerà allutente di tornare utilizzando un web-hook . Ovviamente ci sono altre soluzioni per questo, come Jenkins per una maggiore sicurezza per assicurarti che il tuo codice si basi sulle macchine che gestisci.

Ciò ha cambiato il flusso di lavoro che abbiamo menzionato sopra, ora funziona come segue:

  • Ricevi i dettagli della build dallutente.
  • Attiva unazione Github sul repo specificato.
  • Le azioni Github faranno girare una nuova macchina che ci avviserà con lo stato della build quando fatto, contrassegnerà anche il commit con il Numero di carta Jira su cui stai lavorando.

Il secondo comando è il comando Depoly , che è molto più semplice del comando build, qui dobbiamo solo:

  • Ricevi i dettagli di distribuzione dallutente.
  • Avvia una nuova attività di distribuzione su ogni cluster che contenga il servizio e fornisci lURL dellimmagine in ECR.

flusso di lavoro di distribuzione

Questo è davvero tutto per la distribuzione! solo un lavoro di facilitazione tra due prodotti AWS, confrontiamo questo flusso di lavoro con quello che avevamo prima e vediamo come è cambiata la nostra strategia di rilascio.

Lutilizzo del nuovo processo per distribuire il codice su uno qualsiasi degli stadi (prod, dev, staging) non richiede alcun tipo di unioni , il codice è totalmente indipendente da deployment , potremmo avere 20 dispone di pronto nel ramo principale e sceglie solo di distribuire 10 di essi.

Ma questo implica anche che possiamo avere solo una funzione che è testato sul ramo di sviluppo a meno che due sviluppatori non abbiano accettato di rebase luno sullaltro.

Cronologia di distribuzione e codifica

Questo ci ha anche fornito un rollback strategia contro i problemi di produzione, ora abbiamo un ramo principale con tag per ogni funzione / attività che abbiamo riscontrato, ogni volta che affrontiamo un problema di produzione e desideriamo eseguire il rollback di una funzionalità, possiamo facilmente tornare al punto in cui è iniziata questa funzionalità e ripristinare il commit prima di esso, se possibile.

Inoltre questo ci ha permesso di unire tutte le funzionalità funzionanti sul ramo master, anche se non verranno distribuite, possiamo ancora averle sul master pronte per il prossimo lotto di funzionalità in produzione quando necessario, che sicuramente aiuterà il nostro il team si concentra sulla consegna delle attività senza preoccuparsi di quando lattività verrà fusa nel master per essere distribuita, qui ci uniamo prima e poi ci preoccupiamo delle distribuzioni.

Passaggi successivi

Attualmente stiamo lavorando per automatizzare il nostro processo migliore, comprese le variabili di ambiente e le specifiche della macchina, saranno tutte disponibili come codice, ogni volta che cambiamo quelle specifiche, che si rifletterà automaticamente ect sulle nostre macchine su AWS nel rispettivo Ambiente , non è necessario codificare manualmente quei valori ogni volta su AWS.

Con questo, avremo un migliore controllo e visibilità su tutte le configurazioni dei nostri servizi, tutto nella nostra infrastruttura sarà in codice e un clic per aggiornarlo! Inoltre, ciò rende la modifica della nostra infrastruttura indipendente dal fornitore di servizi, ad esempio potremmo passare da AWS a Google cloud e dobbiamo solo modificare i comandi utilizzati dal servizio di distribuzione per distribuire la nostra infrastruttura sul nuovo fornitore di servizi.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *