Infrastructure as Code è un approccio alla gestione e al provisioning dell'infrastruttura basato sul codice anziché su processi manuali. I vantaggi sono molti, tra cui scalabilità, flessibilità ed efficienza. Ma bisogna mettere in conto anche le sfide che la IaC porta con sé.Per sviluppare, distribuire e scalare applicazioni cloud con maggiore velocità, meno rischi e costi ridotti è necessario astrarre e risolvere in maniera automatica il problema della gestione dell’infrastruttura. Questo può essere fatto con l’Infrastructure as Code, o IaC in breve.
Si tratta di una serie di pratiche e strumenti che astraggono il problema della gestione dell'infrastruttura, ed è un cambiamento di paradigma fondamentale nell'ingegneria del software e nel modo in cui le Ops pensano al provisioning e alla manutenzione delle infrastrutture.
L’infrastruttura è l'insieme di risorse necessarie per lo sviluppo e la messa in produzione dei servizi software. La IaC è la pratica del provisioning e gestione di una infrastruttura attraverso un modello descrittivo che utilizza il codice. Questo approccio sostituisce i processi manuali e cioè gli strumenti di configurazione, script e altro ancora.
Attraverso il codice, i file di configurazione creati con l'Infrastructure as Code descrivono le specifiche dell'infrastruttura. Modificare e distribuire le configurazioni diviene così più facile.
In questo modo la configurazione delle risorse di un centro di calcolo (rete, server, macchine virtuali, load balancer) può essere definita in maniera univoca e gestita con un sistema di controllo di versione.
Negli ambienti di sviluppo Cloud Native è necessario sia che l'infrastruttura possa essere usata e rigenerata a seconda delle necessità, sia che si mantenga coerente in tutte le fasi di sviluppo e messa in produzione.
L’infrastructure as code consente agli sviluppatori di gestire la configurazione dell'infrastruttura con lo stesso processo usato per lo sviluppo del software, evitando, ad esempio, variazioni non riproducibili.
Si ha così la certezza che ogni volta che la configurazione viene applicata in modo automatico si ottenga sempre lo stesso risultato. Una configurazione manuale non riesce né a garantire questo risultato, né a scalare alla dimensione richiesta dalle applicazioni Cloud Native.
Oggi, infatti, la gestione delle infrastrutture è un vero problema in termini di scalabilità. Dai server ai load balancer, dai firewall ai database sino ai cluster di container: la complessità delle architetture software è cambiata rispetto al passato.
Il singolo server non è più il mattone alla base dell'attività di provisioning, gestione dell'ambiente di sviluppo ed esecuzione del software nel cloud. Rispetto al passato, una singola istanza di una singola macchina non è più il core. Il Cloud astrae il server fisico, erogando invece delle ”risorse”. E la gestione manuale non è più efficiente.
Per questi motivi oggi l’Infrastructure as Code è diventata una componente fondamentale per l'adozione della metodologia DevOps e della pipeline di integrazione e distribuzione continua (CI/CD). Entrambi alla base dello sviluppo delle applicazioni Cloud Native.
La IaC è inoltre un approccio estremamente vantaggioso per chi pratica la Site Reliability Engineering, dato che questa si serve dell'ingegneria del software e dell’automazione per svolgere le operazioni IT, tradizionalmente svolte in maniera manuale dai team operativi. Ecco perché IaC e SRE sono strettamente correlate.
Come abbiamo anticipato nel paragrafo precedente, la IaC svolge un ruolo chiave nell'adozione della pipeline di integrazione continua e distribuzione continua (CI/CD)- una delle best practice DevOps - semplificando il provisioning dell'infrastruttura tramite script dedicati. Attraverso la IaC e il modello CI/CD, è possibile contare su una costante automazione e monitoraggio in tutte le fasi del ciclo di vita delle applicazioni, dall'ambiente di test al deployment in produzione.
Tuttavia, per garantire l'omogeneità e prevenire incongruenze, è imperativo che i team di IaC e DevOps operino in stretta collaborazione, adottando procedure di distribuzione e configurazione congruenti. L'uso di Infrastructure as Code facilita notevolmente questo processo, poiché consente a entrambi i team di fare affidamento sulla stessa descrizione per il deployment delle applicazioni, favorendo l’approccio DevOps.
Infine, grazie all'adozione di IaC, è possibile applicare le migliori pratiche di DevOps all'infrastruttura stessa, consentendo a DevOps di sfruttare la stessa pipeline CI/CD impiegata per lo sviluppo software, garantendo coerenza nei test e nei controlli effettuati durante tutto il ciclo di sviluppo.
Infrastructure as Code e DevOps rappresentano quindi un connubio essenziale per ottimizzare l'efficienza operativa. Con questa prospettiva, trasformare l’infrastruttura in codice porta una serie di vantaggi. Permette infatti di ricorrere a tutto il bagaglio di competenze e strumenti usati nella produzione del software: ciclo di vita dello sviluppo software, controllo delle versioni e testing.
L’approccio IaC ha numerosi punti di forza (e se arrivi fino in fondo all’articolo ne sarai pienamente consapevole). Uno di questi è la flessibilità. Si possono infatti suddividere le risorse dell'infrastruttura in componenti modulari combinabili a seconda dei bisogni. Questo favorisce la disponibilità e la scalabilità dei servizi, oltre a facilitare la loro visibilità e il monitoraggio.
Inoltre, documentare e codificare la gestione della configurazione, che si trasforma in file di configurazione, ha un altro vantaggio. È infatti possibile allineare i differenti team che si occupano dello sviluppo dei servizi software, della loro manutenzione e della loro messa in produzione.
Infine, l’approccio IaC è compatibile con modalità di sviluppo del software moderne e scalabili come, ad esempio, l'approccio Agile.
In sostanza, Infrastructure as code vuol dire fare gestione e provisioning dell’infrastruttura usando il codice e un interprete automatico, anziché una serie di processi storicamente gestiti in maniera manuale. Più sotto vedremo alcuni strumenti che consentono di automatizzare la gestione e il provisioning dell’infrastruttura in ambienti diversi.
LEGGI ANCHE: Best practice DevOps da adottare subito in azienda
Le Infrastructure as code possono essere create e gestite con molti strumenti diversi. Questo può creare un po' di confusione, anche perché il mercato è decisamente affollato: ci sono almeno una dozzina di soluzioni di IaC. Il modo più semplice per distinguerle è guardare quale approccio seguono. Ce ne sono due: imperativo e dichiarativo.
Come abbiamo visto l'approccio imperativo prevede che, per raggiungere lo stato desiderato di una infrastruttura, occorra indicare una dopo l'altra le istruzioni per manipolare nel modo corretto il sistema. Un esempio sono i playbook di Ansible.
Invece, l'approccio dichiarativo descrive il risultato che si vuole ottenere e lo strumento si occupa di realizzarlo in modo automatico. Come ad esempio Terraform.
I modelli dichiarativi hanno anche un’altra proprietà che non è presente in quelli imperativi: l’idempotenza. Si tratta di una proprietà per cui una operazione può essere eseguita un numero qualsiasi di volte e produce sempre lo stesso risultato. Detto in altro modo, non importa quante volte viene ripetuta l’operazione, il sistema è sempre nello stato in cui sarebbe se l’operazione fosse stata eseguita una volta sola.
Un esempio per capire questa distinzione lo abbiamo nella plancia delle nostre automobili. Il climatizzatore ci permette di impostare in modo dichiarativo una temperatura a prescindere dalla condizione dell’interno dell’automobile perché è lui che si occupa di raggiungere il livello che vogliamo, riscaldando o raffreddando a seconda della bisogna.
Accanto al climatizzatore c’è invece la radio, che ha i pulsanti del volume, i quali permettono di aumentare o decrescere il volume in modo imperativo, modificandolo ogni volta che vengono azionati.
Vediamo un altro esempio più operativo: se per un progetto voglio realizzare un determinato deployment, con l'approccio dichiarativo devo semplicemente indicare quale immagine docker ho scelto di utilizzare, il numero delle repliche e con quali annotazioni. Invece, con l'approccio imperativo devo descrivere una sequenza di comandi che indichino allo strumento di gestione esattamente quali passaggi eseguire e in quale ordine per arrivare a creare lo stato che voglio.
In molti strumenti la distinzione tra i due differenti tipi di approccio non è sempre così marcata: alcuni utilizzano, in parte, sia l'approccio dichiarativo sia quello imperativo. Alcuni strumenti dichiarativi, infatti, in realtà "nascondono" all'utente delle funzioni imperative. Mentre molti strumenti imperativi hanno comunque forme di automazione di tipo dichiarativo.
La distinzione è comunque utile, come vedremo tra un attimo, perché consente di scegliere lo strumento più adatto ai nostri bisogni e che ci porti i maggiori vantaggi per quello che vogliamo fare.
Dopo il confronto tra approccio imperativo e dichiarativo, approfondiamo un’altra importante distinzione, quella tra infrastruttura immutabile e infrastruttura mutabile. Infatti, la scelta tra queste due infrastrutture rappresenta una decisione cruciale da prendere quando si adotta l'automazione dell’infrastruttura e, quindi, l’Infrastructure as Code.
L'infrastruttura mutabile è - come suggerisce il termine - quella che può essere modificata o aggiornata dopo la sua iniziale creazione. Questa opzione offre ai team di sviluppo la flessibilità di apportare personalizzazioni ad hoc agli elementi di infrastruttura quali reti, database, dischi, server, ecc… qualora necessario, ad esempio, per risolvere problemi emergenti legati alla sicurezza o alle prestazioni. Tuttavia, esiste anche il rovescio della medaglia. La flessibilità può infatti compromettere uno dei vantaggi chiave offerti dall'IaC, ossia la capacità di mantenere coerenza tra le diverse implementazioni o tra le versioni, rendendo più complesso il tracciamento delle variazioni apportate all'infrastruttura.
Per questo motivo, la maggior parte delle implementazioni di IaC preferisce adottare un approccio di infrastruttura immutabile. Tale approccio elimina quasi del tutto le problematiche legate alle configurazioni errate e semplifica notevolmente il mantenimento della coerenza tra ambienti di test e produzione. Inoltre, facilita la conservazione e il tracciamento delle versioni dell'infrastruttura, consentendo un ritorno agevole a versioni precedenti quando necessario.
Una volta che l'infrastruttura immutabile è stata creata, non può né deve essere più modificata. Questo significa che se è necessario apportare modifiche, le modifiche non andranno effettuate sugli elementi di infrastruttura, ma andranno scritte nel codice di IaC e sarà quindi il processo di deploy automatizzato (Continuous Deployment) che si occuperà di aggiornare o sostituire l’infrastruttura esistente. Un’operazione che risulta più pratica di quanto possa sembrare, grazie alla rapidità con cui è possibile creare nuove infrastrutture con l'ausilio di IaC.
Abbiamo già accennato ad alcuni dei benefici della IaC. Ripercorriamo uno per uno i vantaggi principali.
Fare le cose manualmente occupa del tempo e comporta dei costi. La IaC permette di liberare le persone dalla gestione manuale dell'infrastruttura, cosa che consente loro di lavorare di più e meglio sulle altre cose. Nel complesso, si riducono i tempi oltre che i costi per la realizzazione di un progetto.
Utilizzare la IaC consente di automatizzare i processi di deploy e gestione, ma anche di documentare costantemente il lavoro che viene fatto per ciascuna istanza dell'infrastruttura.
Utilizzando sistemi di controllo di versione vengono documentate e tracciate le differenti configurazioni. Inoltre, proprio come accade con il codice, si può testare che funzionino e producano gli effetti desiderati. Questo vuol dire anche comprendere meglio la propria infrastruttura, i suoi punti di forza e le sue debolezze.
È uno degli obiettivi chiave della IaC. Creare degli ambienti che siano stabili, possano scalare rapidamente e in maniera automatica. Evitare la creazione di configurazioni ad hoc che non sono tracciate e che non possono essere replicate. O, più semplicemente, che sono differenti da quelle utilizzate in altre fasi della pipeline.
La IaC tratta le funzioni di computazione, storage e networking come codice: questo vuol dire che vengono istanziate ogni volta nello stesso modo. Una conseguenza positiva è che si possono implementare e seguire standard e policy di sicurezza in maniera trasversale attraverso tutte le fasi dello sviluppo e della produzione, senza dover fare una review ad ogni passaggio.
Inoltre, in caso di interruzione improvvisa dei servizi, è possibile tornare rapidamente all'ultima stato stabile del sistema, riducendo così in maniera drastica i tempi di recupero degli incidenti.
Non c'è rosa senza spine. I vantaggi della IaC sono numerosi, ma portano con loro sfide complesse. I punti di attenzione da presidiare sono infatti molto importanti e determinano il successo o l'insuccesso di una soluzione IaC. Questi sono i principali.
Gli strumenti sviluppati da terze parti rispetto ai vendor della tecnologia di base comportano il rischio di non essere sempre aggiornati. Nel caso di nuove funzionalità cloud, ci può essere un ritardo prima che vengano implementate nello strumento di gestione della IaC che utilizziamo. Questo può non essere un problema, oppure, alle volte, può esserlo.
Nel secondo caso, le soluzioni possono essere due. Estendere in modo autonomo le funzionalità dello strumento, oppure introdurre altri strumenti secondari che integrino lo strumento IaC principale. In entrambi i casi però aumenta la complessità e diminuisce la velocità di esecuzione.
Per utilizzare gli strumenti di IaC occorre saper usare l'HashiCorp Configuration Language (HCL). Ma, anche se vengono utilizzati linguaggi già noti, come Python o Ruby, il problema è sostanzialmente quello di capire la logica e le convenzioni da utilizzare. Se non si capiscono i concetti chiave della IaC - come l'approccio dichiarativo per esempio - nascono problemi.
La IaC consente di risolvere alcuni problemi tipici degli ambienti di DevOps. Tuttavia incontra anche delle difficoltà di mantenimento delle sue funzioni quando viene utilizzata da gruppi molto ampi di sviluppatori.
Non c'è una regola fissa, ma secondo l'esperienza di molti quando viene superata la soglia dei 100 sviluppatori mantenere la tracciabilità e il versionamento delle configurazioni diventa sempre più complesso o addirittura impossibile da gestire in tempi e con sforzi ragionevoli.
Anche la gestione degli accessi diventa un problema quando vengono superate determinate soglie di numerosità. La definizione dei ruoli e dei permessi nelle organizzazioni numerose è complessa e difficile da gestire nel tempo e quella delle IaC è particolarmente critica.
La curva di apprendimento dell'approccio IaC e dei singoli strumenti a disposizione può essere ripida ma può anche variare molto a seconda di quali strumenti vengono scelti. Vediamo in conclusione quali sono.
Esistono molti tool per la gestione dell'Infrastruttura come Codice. Non sono tutti uguali né seguono lo stesso approccio, come abbiamo visto prima.
Molti sono open source (come Terraform e Pulumi), altri sono legati a piattaforme specifiche: CloudFormation di AWS (Amazon), Resource Manager di Azure (Microsoft) e Google Cloud Deployment Manager. Ma ce ne sono altri ancora. Vediamo in modo più analitico i principali.
Molti di questi strumenti sono pensati per essere legati a Kubernetes (K8s), il sistema di orchestrazione di container open source per automatizzare la distribuzione, la scalabilità e la gestione del software.
Le piattaforme per le applicazioni Cloud Native offrono una serie di vantaggi oggi irrinunciabili: velocità di rilascio, facilità di gestione, riduzione dei costi, scalabilità, affidabilità dei sistemi.
Tutto questo richiede nuovi strumenti e nuove modalità di sviluppo e gestione. Per quanto riguarda l'infrastruttura, da dieci anni a questa parte è diventato irrinunciabile l'utilizzo delle pratiche e degli strumenti di Infrastructure as Code.
Questo approccio è una vera rivoluzione per lo sviluppo del software e il provisioning e manutenzione delle infrastrutture. La IaC oggi è una componente fondamentale per l'adozione della metodologia DevOps e della pipeline di integrazione e distribuzione continua (CI/CD). Tuttavia, anche se IaC porta con sé dei vantaggi innegabili (velocità, riduzione dei costi, standardizzazione, sicurezza), richiede anche delle competenze specifiche per capirne il funzionamento, scegliere gli strumenti adatti e governare le operazioni.