Infrastructure as code

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.

Cos’è l’Infrastructure as code (IaC)?

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.

A cosa serve la IaC nel Cloud Native?

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.

Click me

Infrastructure as Code e DevOps

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: flessibilità e scalabilità

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

Tipologie di Soluzioni IaC

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.

  • L'approccio imperativo definisce i comandi specifici necessari per ottenere la configurazione desiderata. I comandi vengono eseguiti automaticamente in sequenza. È come definire un percorso indicando manualmente tutti gli step, uno dopo l'altro. Ovviamente, per avere i risultati attesi la sequenza dei comandi deve essere quella corretta.
  • L'approccio dichiarativo, invece, definisce lo stato desiderato del sistema (cioè quali risorse devono essere attive e con quali proprietà). Lo strumento software dedicato si occupa autonomamente dell'esecuzione dei passi necessari per raggiungere questo stato. Questo garantisce una maggiore flessibilità, ma di contro si ha meno controllo su quello che succede passo per passo nel sistema.

La distinzione tra approccio 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.

Infrastruttura immutabile e infrastruttura mutabile: quale scegliere?

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.

Infrastructure as code: i vantaggi

Abbiamo già accennato ad alcuni dei benefici della IaC. Ripercorriamo uno per uno i vantaggi principali.

Riduzione dei tempi e dei costi

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.

Documentazione e test

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.

Ambienti più standardizzati, stabili e scalabili

È 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. 

Sicurezza, disaster recovery

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.

Sfide e criticità della IaC

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.

Strumenti non aggiornati

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.

Comprensione della IaC

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.   

Mantenimento con grandi gruppi

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. 

Gestione degli accessi e permessi

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.

Tutti gli strumenti per la IaC

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.

  • Il Config Connector di Google, ad esempio, offre la possibilità di gestire le risorse del cloud di Google (attualmente più di 150) tramite K8s. Config Connector offre soprattutto un metodo unico e automatizzato per configurare più servizi e risorse sparse in parti differenti della piattaforma Google Cloud grazie agli strumenti e alle API esposte da Kubernetes. GCC utilizza un approccio dichiarativo per la GCP che alleggerisce molto il lavoro dei DevOps che usano la piattaforma di Google. 
  • Terraform di HashiCorp è uno strumento multipiattaforma cloud tra i più diffusi se non il più diffuso, perché capace di gestire una infrastruttura su varie piattaforme tra le quali AWS, Azure, GCP, Oracle Cloud, Alibaba Cloud e persino Kubernetes ed Heroku. Il punto di forza di Terraform è la capacità di consentire ai suoi utilizzatori di raggiungere lo stato desiderato con un’infrastruttura multicloud e il potere espressivo del linguaggio utilizzato per la definizione degli obiettivi.
  • Puppet è un altro popolare strumento di gestione della configurazione che si integra con i principali provider di cloud come AWS, Azure, Google Cloud e VMware, consentendo di automatizzare il deployment di una infrastruttura su più piattaforme cloud. Puppet è basato su un approccio a modelli, pensato per gli amministratori di sistema. I server Puppet possono essere installati su uno o più server, mentre è necessario installare l'agente Puppet su tutti i nodi che devono essere gestiti. Il modello è quindi un modello client-server o agent-master.
  • Chef è un altro strumento di gestione della configurazione tra i più diffusi utilizzati nei processi di integrazione e distribuzione continui, anche perché tra i primi ad essere stato realizzato. Chef (il nome deriva dal fatto che i file di configurazione di tipo dichiarativo sono chiamati “ricette”) è indipendente dalla piattaforma cloud su cui lavora, nel senso che è compatibile con molti provider di servizi cloud come AWS, Microsoft Azure, Google Cloud Platform, OpenStack e altri. 
  • Pulumi è uno strumento relativamente nuovo, pensato per Kubernetes, che ha la particolarità di supportare differenti linguaggi di programmazione per creare la IaC. Quelli forniti di default sono Python, TypeScript, JavaScript, Go, C#, F#. Pulumi ha rilasciato da poco un Kubernetes Operator. Permette di fare il deployment di infrastrutture (Pulumi Stacks) in cui possono essere attivate virtual machine, block storage, cluster gestiti da Kubernetes, API, funzioni serverless e altro ancora
  • Ansible di Red Hat (a sua volta acquisita da Ibm) è uno strumento open source che consente di automatizzare le procedure di configurazione e gestione dei server a cui sono state aggiunte funzionalità di IaC sia per il cloud sia on premises. Ha poi la particolarità di poter funzionare come strumento agentless ricevendo comandi via Ssh o WinRM.
  • Saltstack è uno strumento software per la configurazione di infrastrutture simile a Terraform o Puppet che ha dalla sua alcuni vantaggi tra i quali la velocità e la versatilità delle opzioni. Salt (come è anche chiamato) è disponibile per più di 25 piattaforme cloud pubbliche o private e utilizza un sistema di distribuzione delle configurazioni veloce resa sicura con AESe Reliable Asynchronous Event Transport (RAET).
  • CloudFormation di AWS e gli Azure Resource Templates sono strumenti sviluppati rispettivamente da Amazon e Microsoft per la IaC delle proprie infrastrutture. Ovviamente CloudFormation ha un'integrazione con i servizi di AWS molto avanzata, mentre Resource Templates di Azure segue un approccio differente e offre una serie di esempi di gestione coerente per la piattaforma cloud di Microsoft. Infine, il Cloud Development Kit di AWS (AWS CDK), un framework simile a Pulumi ma specifico per l'ambiente di Amazon.

In conclusione

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. 

guida SRE