In questo articolo esploreremo la transizione dal ciclo di vita del software tradizionale al contesto del DevSecOps, approfondendo aspetti legati a DevOps e alla CI/CD. Inoltre, ci concentreremo sui problemi affrontati durante questo percorso e sulle soluzioni sviluppate nel corso del tempo, con un particolare riguardo su GitLab, una piattaforma di DevSecOps unificata.
SDLC Tradizionale
Prima di introdurre concetti di DevOps e DevSecOps, è importante fare un tuffo nel passato per capire come anni fa venivano sviluppati e rilasciati i software applicativi.
Credo tutti abbiamo già sentito parlare di “modello waterfall” (in italiano “modello a cascata”). Esso rappresenta il Software Development Life Cycle (SDLC) tradizionale, ovvero quello in cui si seguono una serie di step fino ad arrivare al prodotto (software) finito e consegnato al cliente.
Si inizia con una fase di analisi e raccolta dei requisiti, dopodiché si passa alla fase di progettazione dove si progetta il software in modo che rispecchi i requisiti.
Dopo aver terminato la progettazione segue l’implementazione (scrittura del codice applicativo), per poi procedere con i test finalizzati a verificare che tutto funzioni come da aspettative. Successivamente, si procede con il deploy in ambiente di produzione.
Vi è anche una fase di manutenzione utile nel caso in cui escono dei bug durante l’utilizzo del software da parte del cliente oppure in caso di piccole modifiche oppure aggiunte di funzionalità (features) richieste sempre dal cliente.
Il problema dell’approccio waterfall è che il cliente cambia sempre idea! C’è il serio rischio che durante la fase di progettazione, o addirittura durante quella di implementazione, il cliente rivoluzioni tutto con nuovi requisiti spesso incompatibili con quelli raccolti nella prima fase di analisi.
Il team di sviluppo non è mai pienamente certo di soddisfare i requisiti del cliente in quanto possono variare nel tempo. Questo come conseguenza comporta fare uno o più passi indietro, ovvero si rischia di tornare alla fase iniziale di analisi e raccolta dei requisiti e di rifare la progettazione e l’implementazione.
Oggi per fortuna la metodologia waterfall è quasi completamente un ricordo: non viene più utilizzata a meno di casi particolari.
Metodologia Agile
Il subentro della metodologia agile ha cambiato tutto! A differenza dell’approccio waterfall, è basata sulla distribuzione continua del software in maniera rapida ed iterativa (ciclica).
L’obiettivo è quello di rilasciare rapidamente le modifiche al software in piccole porzioni, arrivando pian piano a soddisfare le esigenze del cliente che, come sappiamo, possono mutare nel tempo.
In questo modo si tenta di ridurre il rischio di fallimento, sviluppando il software in finestre di tempo limitate chiamate iterazioni o sprint, che durano in genere da 1 a 4 settimane.
Ogni iterazione è come un piccolo progetto a sé stante e deve contenere tutto ciò che è necessario per rilasciare un piccolo incremento nelle funzionalità del software: quindi ogni volta si procede con la pianificazione, analisi dei requisiti, progettazione, implementazione, test, deploy e revisione.
Abbiamo però un side-effect: la velocità con cui vengono apportati i cambiamenti potrebbe impattare sulla qualità del software che andiamo a rilasciare! Gli sviluppatori per completare lo sprint nei tempi stabiliti potrebbero trascurare alcuni aspetti relativi alla qualità del software.
In questo contesto, il DevOps entra in gioco a gamba tesa e si propone come soluzione!
Development & Operation
In generale, in un’organizzazione possiamo distinguere due team: quello di Development e quello di Operation.
Il team di Development si occupa dello sviluppo del software, ovvero crea applicazioni seguendo le indicazioni del business nel modo più veloce possibile. L’obiettivo è quello di arrivare rapidamente in ambiente di produzione e ridurre al minimo il tempo del “time to market”.
Il team di Operation, invece, si occupa di gestire le applicazioni in ambiente di produzione. Ha un duplice obbiettivo: rendere l’ambiente di esercizio il più stabile e sicuro possibile, ed evitare impatti negativi relativi al deploy di applicazioni non sufficientemente stabili e preformanti.
È come se avessimo un muro (detto “muro di confusione”) tra i due team:
Il team di Development ha la pressione del business e tende a rilasciare le applicazioni fin troppo velocemente a scapito della qualità e delle prestazioni, mentre dall’altra parte del muro c’è il team di Operation che richiede stabilità e requisiti di qualità, performance e sicurezza per l’applicazione deployata in ambiente di produzione.
A causa di questi obiettivi parzialmente in conflitto tra questi due team di lavoro, si è sempre avuta una sorta di diffidenza reciproca, che spesso si traduce in inefficienza.
Questo conflitto viene risolto con il DevOps, ovvero un approccio che spinge questi due team a cooperare per rendere il processo di deploy veloce e al contempo sicuro.
DevOps
La parola DevOps potrebbe sembrare un concetto piuttosto semplice, infatti, si compone dalla parola “dev” (development) e dalla parola “ops” (operations). Come allude la parola stessa, consiste nel riunire queste due aree funzionali storicamente separate. L’obiettivo è quello di colmare il divario (rimuovere i silos) tra i team di sviluppo e di operazioni.
Per definizione, il DevOps è un insieme di pratiche da adottare volte ad accelerare i processi che consentono ad un’idea (es. una nuova feature nel software, una richiesta di miglioramento, fix di bugs, ecc.) di passare dallo sviluppo al deployment in ambiente di produzione, assicurando un’elevata qualità.
Con il DevOps i due team non agiscono più separatamente, ma si affidano all’automatizzazione per velocizzare processi manuali che sono da sempre lenti.
Il punto chiave è rendere automatici, e di conseguenza obbligatori, una serie di processi in sequenza, come quello di build, test, rilascio e deploy attraverso l’utilizzo di pipeline di CI/CD e altri tool.
Che cosa è il DevOps?
Il concetto di DevOps è stato introdotto circa 10 anni fa, tuttavia, oggi ha un significato più ampio in quanto è ancora in fase di evoluzione. Comprende tantissime aree, e viene adottato e adattato in base al contesto e agli obiettivi aziendali.
Il DevOps non è assolutamente un ruolo, un team oppure una riorganizzazione del personale. Chi pensa che il DevOps possa essere realizzato attraverso una riorganizzazione o uno sforzo di assunzione sta solamente guardando ad un solo pezzo del puzzle del DevOps. La struttura organizzativa e i ruoli del team sono secondari rispetto alle pratiche cooperative sottostanti sul lavoro.
Inoltre, il DevOps non significa semplicemente implementare una serie di tool di DevOps. Non ha senso utilizzare questi tool senza aver ben chiaro in mente i principi base. L’automazione, punto cardine del DevOps, è solo l’esercizio del potere: un’automazione imprudente può causare tanti danni quanto un’automazione saggia può portare benefici.
Fatte queste considerazioni, possiamo dare una definizione più generale del DevOps: è quella disciplina radicata nella collaborazione e nella comunicazione, resa possibile rimuovendo le barriere percepite tra i team, creando fiducia in una cultura di apprendimento e miglioramento continuo, e attingendo da comprovate pratiche tecniche e gestionali che lavorano verso l’obiettivo comune di accorciare i cicli di distribuzione del software e migliorare la stabilità delle implementazioni.
Shift-Left
Uno dei pilastri fondamentali del DevOps è il cosiddetto Shift Left, a volte chiamato anche Start Left. Descrive il principio di effettuare test e controlli sulla qualità del codice nelle prime fasi del ciclo di vita dello sviluppo del software.
Con la diffusione delle metodologie agili, il test e i controlli di qualità del software non devono attendere finché gli sviluppatori non consegnano il loro codice. Possono invece accadere mentre gli sviluppatori stanno sviluppando. Visivamente, i test e i controlli sulla qualità del software si spostano a sinistra: da qui l’origine del termine shift-left.
I vantaggi dello shift-left sono molteplici: innanzitutto possiamo scoprire tempestivamente i problemi nel software, inoltre, possiamo garantire, una volta che il software viene distribuito, che questo sia stabile e richieda meno manutenzione.
Con lo shift-left gli sviluppatori sono al centro del cambiamento: sono in prima fila! Questo però non significa che addossiamo più responsabilità ai poveri sviluppatori, ma bensì gli stiamo riducendo il carico di lavoro trasformando problemi critici di “fine gioco” in banali soluzioni di “inizio gioco”.
I test manuali e i controlli di qualità richiedono molto tempo, sono frustranti e introducono errori umani. Questo andrebbe a rafforzare il muro tra “dev” e “ops”, ed è l’opposto a ciò che il DevOps cerca di fare. Per questo motivo lo shift-left richiede automazione!
Pratiche di CI/CD
L’automazione è il punto focale del DevOps per unire il team Dev e Ops, e si può applicare in vare modalità. La più importante fa utilizzo di pipeline di Continuous Integration e Continuous Deployment (CI/CD).
Continuous Integration
La Continuous Integration (CI) è una pratica che si applica quando lo sviluppo del codice avviene attraverso l’utilizzo di un sistema di versionamento (es. Git).
Questa pratica spinge i developer ad integrare frequentemente le modifiche sviluppate in locale verso una code base condivisa (repository), per poi poter eseguire una pipeline che automatizza il processo di build (compilazione) e l’esecuzione di test automatici, come ad esempio quelli di unità, di qualità e di integrazione.
Nota: per poter effettuare i test di integrazione possiamo pensare di affidarci al mock oppure di deployare l’applicazione in un ambiente di staging che verrà subito distrutto dopo i test condotti.
Dunque, ad ogni nuova integrazione (es. quando viene aperta una pull request) viene eseguita questa pipeline. Nel caso la compilazione automatica oppure i test automatici fallissero, anche la pipeline fallirebbe. Lo sviluppatore è costretto a rivedere il codice, fixandolo e migliorandolo in modo che i test passino con successo (assicurando di conseguenza la correttezza e la qualità del software rilasciato).
Se i test passano con successo, la CI effettua il packaging (impacchetta l’artefatto buildato) e lo deposita all’interno di un artifact repository, versionandolo ed aggiungendo altri metadati.
Continuous Deployment
Con il Continuous Deployment (CD), oltre agli automatismi previsti dalla CI, viene automatizzato tramite pipeline anche il deploy in ambiente (es. in ambiente di collaudo e di produzione). Infine, nel caso in cui il deploy in produzione avviene manualmente, essendo ragionevolmente uno step molto delicato, parleremo invece Continuous Delivery.
Di solito quando si pensa al DevOps, viene subito in mente il simbolo dell’infinito:
Questo particolare simbolo allude agli step di CI/CD che si ripetono in maniera ciclica: plan, create, verify, package, release (deploy), configure e monitor.
Si parte sempre dalla pianificazione , poi si sviluppa il codice (in base alle specifiche delineate nella fase di pianificazione), dopodiché viene fatta richiesta di integrazione del codice all’interno della code base condivisa, tuttavia, prima di essere integrato viene revisionato (optional) e viene avviata una pipeline di CI/CD che effettua automaticamente la compilazione (build) e la verifica (test) del codice, fino depositare l’artefatto prodotto dalla build all’interno di un artifact repository (es. per progetti Maven/Java quello che verrà depositato potrebbe essere un JAR e il relativo POM).
Dopodiché, la pipeline procede con il rilascio vero e proprio (deploy) del software in produzione.
Come già accennato questo step di deploy può anche avvenire manualmente nel caso adottiamo la pratica di Continuous Delivery piuttosto che quella del Continuous Deployment.
Una volta effettuato il deploy, si entra nella fase di operate: qui il team va a testare la stabilità del software ed eventualmente va a configurarlo se necessario. In parallelo, gli utenti finali e/o i tester iniziano ad utilizzare il software.
Monitoraggio
Il software deployato va però anche monitorato! Gli utenti finali e/o i tester possono segnalare i problemi (issue) durante l’utilizzo del software (es. bug e casi non gestiti), oppure fornire suggerimenti su come migliorarlo o su ciò che vogliono sia ancora implementato.
Tutto questo chiaramente verrà affrontato in un una prossima iterazione / sprint. Quindi torneremo nuovamente alla fase di pianificazione dove verrà aggiornato il backlog in base alle nuove esigenze del progetto e ai bug da fixare, si definiscono delle milestone e le attività si suddividono in sprint, e si prosegue con il loop (coding, testing, …).
Nella fase di monitoraggio ci si avvale anche di una serie di tool per appunto monitorare automaticamente le performance del software (es. in termini di CPU/RAM), oppure per analizzare i log con lo scopo di accorgerci di eventuali errori o in generale di comportamenti anomali degni di attenzione. I dati raccolti in real time vengono poi visualizzati su dashboard grafiche.
DevSecOps
Cosa è il DevSecOps? Semplicemente: DevOps + Security.
Il DevSecOps, chiamato a volte anche SecDevOps, possiamo vederlo come un’estensione del DevOps, che però pone particolare attenzione sulla sicurezza del software che viene rilasciato. La sicurezza diventa parte integrante della qualità!
L’obiettivo è quello di riunire tre team (team di development, di operation, e di security) in modo da abbreviare i tempi di rilascio, ridurre i costi, rafforzare la sicurezza ed aumentare la produttività degli sviluppatori.
Lo shift-left è applicato anche alla sicurezza: spostiamo verso sinistra (nel ciclo di vita dello sviluppo del software) i controlli sulla sicurezza del software. Piuttosto che affrontare revisioni e ispezioni di sicurezza alla fine del processo e trovare brutte soprese, in questo modo ci pensiamo prima!
Con il DevSecOps vogliamo incorporare la sicurezza in tutto il ciclo di vita del software in modo da ridurre le vulnerabilità di sicurezza. Tutti sono più felici in quanto il team DevOps assicurerà il rispetto di queste best practice e controlli di sicurezza.
Nella pipeline di CI/CD verranno introdotti ulteriori job, racchiusi in opportuni stage, che valutano e verificano la security applicativa, come ad esempio:
- Static Application Security Testing (SAST), per verificare la presenza di vulnerabilità di sicurezza nel codice sorgente;
- Dynamic Application Security Testing (DAST), per testare la sicurezza di un applicativo in running simulando attacchi di vario genere;
- Secret Detection, per verificare la presenza di dati sensibili come password nell’history del repository applicativo;
- Dependency Scanning, per controllare se il software utilizza dipendenze di progetto ad alto rischio (es. versioni di componenti OSS con vulnerabilità note);
- Container Scanning (per verificare la presenza di vulnerabilità nelle immagini Docker utilizzate per virtualizzare l’applicativo);
- …
GitLab, piattaforma di DevSecOps
Applicare il DevSecOps nella tool chain software solitamente non è un processo immediato, ma richiede molteplici configurazioni ed integrazioni tra tool.
Fortunatamente, GitLab viene in nostro aiuto, proponendosi come DevSecOps platform per la gestione del ciclo di vita del software, dalla fase di planning fino a quella del deploy in produzione.
La piattaforma GitLab è conosciuta specialmente per la gestione di repository Git in un contesto distribuito e basato sulla collaborazione tra developers. Tuttavia, non è limitato solo a questa funzionalità, ma ne fornisce tante altre che si rivelano utili durante lo sviluppo e il rilascio del nostro software, sia in ottica di DevOps che di DevSecOps:
- Pianificazione del lavoro;
- Suddivisione ed assegnazione dei task ai membri del team;
- Code review;
- Build e gestione di flussi di CI/CD tramite pipeline;
- Security applicativa integrata facilmente in pipeline;
- Gestione del deploy in ambiente (es. di produzione);
- …
In figura viene rappresentato un processo in linea con il DevSecOps implementabile su GitLab:
Anche se Gitlab è open-source, è suddiviso in due edizioni: la community (CE) che è gratuita, e l’enterprise (EE) che prevede anche piani a pagamento e vanta di un maggior numero di funzionalità. La versione CE soddisfa maggior parte dei requisiti per la gestione di un progetto / team secondo i paradigmi del DevSecOps, la versione EE aggiunge ulteriori funzionalità, garantisce update continui per bug fixing e permette al team di contattare il team GitLab con risposte garantite da SLA contrattuali.
GitLab è disponibile nelle seguenti versioni:
- Cloud (gitlab.com)
- Dedicated
- Servizio SaaS single-tenant;
- GitLab viene deployato su una cloud region AWS a scelta;
- Completamente isolato, ospitato, e gestito da Gitlab Inc.
- Self-managed
- Soluzione on-premise;
- Prevede l’installazione, gestione e mantenimento di una propria istanza GitLab;
- Modalità di installazione: Source, Linux Package, Docker, Helm.
Di seguito le funzionalità offerte finora da GitLab (v. 16.7) per ogni fase operativa del DevSecOps:
Visita il sito ufficiale di GitLab e consulta la sezione dedicata di Profesia per ricevere maggiori informazioni sul prodotto e conoscere i vantaggi dell’utilizzo di una DevOps Platform all’interno dei tuoi processi di sviluppo.