L’adozione di un flusso di lavoro CI/CD nello sviluppo di applicazioni sta guadagnando sempre più terreno. Tuttavia, la scalabilità e l’ottimizzazione di CI/CD rappresentano una problematica complessa.
In questa discussione, analizzeremo nel dettaglio questa sfida e cercheremo di capire come sia possibile scalare e perfezionare CI/CD. Continuate a leggere per saperne di più!
Al giorno d’oggi, lo sviluppo di applicazioni coinvolge tipicamente team di sviluppatori con competenze diverse. Ciascun membro o gruppo ha un compito specifico all’interno del progetto, operando sulla sua area di competenza.
Al termine del progetto, ci ritroviamo con una serie di frammenti di codice da assemblare. A seconda delle modalità di lavoro di ciascuno, l’integrazione di queste componenti può richiedere molto tempo.
CI/CD, ovvero Integrazione Continua e Consegna/Distribuzione Continua, offre una soluzione a questo problema, garantendo il rilascio degli aggiornamenti senza ritardi o conflitti inutili. Esaminiamo più da vicino questo processo.
Integrazione Continua
La CI, o Integrazione Continua, comprende l’insieme dei processi che permettono di pubblicare regolarmente modifiche e aggiunte al codice in un ramo condiviso del progetto. Ciò consente di testare il codice e di apportare modifiche e miglioramenti in tempo reale. L’obiettivo principale è quello di verificare ogni elemento attraverso la creazione di test.
Questa pratica continua evita di dover controllare tutto in blocco alla fine e di dover lavorare su troppi elementi contemporaneamente. L’esecuzione di test unitari è fondamentale per garantire ciò. In questo modo, è più facile individuare gli errori e assicurarsi che il codice venga compilato correttamente senza creare regressioni.
Consegna Continua
La Consegna Continua, o CD, integra i processi di integrazione e test continui che possono essere raggruppati in contenitori e pronti per la produzione. In altre parole, essa raccoglie il codice e i test eseguiti e li rende disponibili per la produzione tramite automazione.
Anche se richiede l’intervento umano, diventa automatizzata nel mettere “online” tutto ciò che è stato fatto in modo integrato e completo. Concretamente, grazie alla distribuzione continua, la nostra applicazione viene sviluppata in modo da essere sempre pronta per il rilascio, in qualsiasi momento.
Distribuzione Continua
Sebbene i concetti di Consegna Continua e Distribuzione Continua siano simili, esistono delle differenze. Anche se l’obiettivo è lo stesso, ovvero l’implementazione dell’applicazione in produzione, i mezzi per raggiungerlo sono diversi. La differenza fondamentale tra Distribuzione Continua e Consegna Continua è il rilascio.
Infatti, l’implementazione continua consente di distribuire direttamente ogni modifica che supera le diverse fasi della pipeline. Nella consegna continua, è invece necessaria una fase di validazione umana prima del rilascio.
Scalare CI/CD
Quando il numero di microservizi aumenta, diventa quasi inevitabile dover scalare CI/CD. L’aumento dei microservizi porta a diverse pipeline collegate a un unico repository Git, il che aumenta il carico del server CI e riduce le prestazioni.
Per scalare CI/CD, è necessario creare una pipeline di sviluppo standardizzata e automatizzata per tutti i team, garantendo la qualità dei rilasci dei singoli sviluppatori e dei team. Ciò semplifica anche la gestione della pipeline.
La scalabilità può essere raggiunta definendo un processo CI per l’esecuzione di test unitari e la convalida della qualità del codice fornito.
Successivamente, si implementa un processo CD per creare le immagini e distribuirle negli ambienti in modo continuo e, infine, si definisce un processo per la creazione e la distribuzione delle immagini nell’ambiente di produzione.
Passaggi per scalare CI/CD
Il primo passo consiste nell’allineare la pipeline con gli architetti e coinvolgere i team leader. Successivamente, si associa i rami Git agli ambienti (develop -> sviluppo e master -> [omologazione e produzione]). Quindi, si attiva il CI Job ad ogni Pull Request e il CD Job a ogni modifica nei branch associati.
È possibile creare un flusso di lavoro standardizzato da seguire sia per CI che per CD.
Il flusso di lavoro CI Job si sviluppa in 7 fasi:
- Analisi del ramo di origine e destinazione della Pull Request;
- Verifica che l’unione non presenti conflitti che richiedono una risoluzione manuale;
- Esecuzione di test unitari;
- Compilazione del pacchetto per verificarne l’integrità e la compilabilità del codice;
- Attivazione della convalida della qualità del codice;
- Incremento e salvataggio della versione del progetto nel ramo di origine;
- Notifica del repository Git della Pull Request in caso di successo o fallimento tramite Webhook o chiamata Rest API (Git Repository).
Il flusso di lavoro CD segue il percorso seguente:
- Verifica del ramo notificato;
- Creazione dell’artefatto utilizzando lo strumento di compilazione specifico del progetto su cui si sta lavorando;
- Dopo l’arrivo dell’artefatto, i progetti della libreria vengono inviati al Nexus per l’archiviazione e il flusso termina.
Le azioni successive sono:
Passaggio 1: creazione di un’immagine Docker per l’artefatto generato, con applicazione della versione dell’artefatto all’immagine Docker.
Passaggio 2: caricamento dell’immagine nel registro Docker.
Passaggio 3: distribuzione tramite rollout delle immagini tramite Kubernetes.
Per i progetti applicativi in ambiente di approvazione/produzione, si seguono i passaggi 1 e 2 descritti sopra e poi si procede come segue:
- Distribuzione tramite rollout delle immagini tramite Kubernetes nell’ambiente di approvazione;
- Il processo si interrompe per attendere l’approvazione della distribuzione in produzione;
- Se approvata, l’immagine approvata viene promossa per la produzione;
- In caso contrario, si ripristina l’immagine nell’ambiente di approvazione.
Ottimizzazione CI/CD
CI/CD migliora il ciclo di sviluppo dell’applicazione e risolve le problematiche derivanti dall’integrazione di nuovo codice e dall’aumento della frequenza di rilascio.
Di seguito, alcuni consigli per ottimizzare ulteriormente l’utilizzo di CI/CD:
Dare priorità alla correzione di una build fallita
Quando una build fallisce, la sua riparazione dovrebbe essere la priorità del team. Se non è possibile ripristinarla in pochi minuti, il team deve decidere se rimuovere il codice o disabilitare la funzionalità interessata.
L’obiettivo della correzione di una build fallita è quello di garantire che la build produca sempre codice funzionante e pronto per il rilascio.
Rilasci piccoli e frequenti
La stabilità dell’applicazione è generalmente a rischio ogni volta che si esegue un rilascio. Di conseguenza, tendiamo a distanziare i rilasci nel tempo. Il problema di questo approccio è che si accumulano troppe modifiche. Una di queste modifiche potrebbe causare problemi, costringendoci a ripristinare anche le altre che funzionavano correttamente.
Applicate il modello strangolatore e suddividete le modifiche complesse in blocchi più piccoli e semplici. Rilasciando più frequentemente e lavorando su piccoli batch, si riduce il rischio associato al rilascio.
Automatizzare i test di controllo qualità per mitigare i rischi
Quasi tutti gli sviluppatori hanno sperimentato lo scenario “funzionava sulla mia macchina”, poiché gli ambienti di sviluppo locale spesso differiscono. Ci possono essere molte differenze tra l’ambiente locale e l’ambiente di produzione. È possibile ottimizzare CI/CD automatizzando le attività di controllo qualità (QA), come i test del browser, riducendo il rischio che un bug arrivi all’applicazione live.
Affidarsi ai test automatizzati
Per validare l’integrazione di nuovo codice da parte di uno sviluppatore, CI si affida a una suite di test automatizzata e affidabile. Il primo test è che il codice venga compilato con successo. Poi, si possono aggiungere tutti i test ritenuti critici.
Quanti test dovrebbero essere inclusi? Per capirlo, tenete presente che l’obiettivo di CI è fornire un feedback il più rapidamente possibile. Se uno sviluppatore deve aspettare un’ora per avere un feedback, il processo non funziona. Ovviamente, ci sarà sempre la possibilità che qualcosa sfugga, ma quando si individua un bug in produzione, è importante creare un caso di test e includerlo nel ciclo CI.
Considerare sempre la sicurezza
La sicurezza è un aspetto fondamentale di qualsiasi strumento CI/CD. Questo strumento deve essere integrato nelle configurazioni o negli ambienti esistenti. CI/CD richiede che tutti gli strumenti di test di sicurezza vengano richiamati a livello di codice e che i risultati vengano aggregati in un’unica posizione. Cercate strumenti che offrano API per audit di crittografia automatizzati.
Vantaggi della scalabilità e ottimizzazione di CI/CD
Oltre a incrementare l’efficienza dei team di sviluppo, la scalabilità e l’ottimizzazione di CI/CD offrono anche altri vantaggi, tra cui:
Riduzione dei costi generali
Le ore di sviluppo sono generalmente fatturabili, ma cosa dire del tempo impiegato per la distribuzione manuale di codice o file? L’automazione di gran parte del flusso consente di risparmiare tempo per attività fatturabili, un aspetto positivo per tutti. I test automatizzati permettono anche di identificare gli errori in anticipo, evitando che si manifestino nel controllo qualità o in produzione, o peggio, che vengano trovati dal cliente. Più bug vengono risolti nello stesso arco di tempo, un chiaro vantaggio.
Rilasci con meno bug e rischi
È possibile individuare i bug nelle fasi iniziali del processo di sviluppo, grazie al rilascio più frequente di piccole modifiche. L’implementazione di test automatizzati in tutte le fasi dello sviluppo riduce il rischio di errori e facilita il ripristino di modifiche minori in caso di necessità.
Risposta più rapida alle condizioni di mercato
Le condizioni di mercato sono in continua evoluzione. Supponiamo di scoprire che un nuovo prodotto sta perdendo entrate o che un numero maggiore di clienti acceda al sito da smartphone anziché da laptop. In tal caso, sarà molto più semplice apportare una modifica rapida se la consegna continua è stata ottimizzata.
Fiducia
Se CI/CD è stato ottimizzato, e quindi è disponibile una solida suite di test, la sicurezza di non rilasciare bug aumenta notevolmente. La trasparenza nel processo e la formazione del resto del team e dei clienti contribuiscono anche a rafforzare la loro fiducia nel team di sviluppo.
Considerazioni finali
CI/CD velocizza i processi di integrazione e consegna. Tuttavia, è fondamentale scalarlo e ottimizzarlo per evitare che il processo diventi controproducente a causa della crescente complessità.
È inoltre possibile consultare i migliori strumenti CI disponibili.