Vai al contenuto
Infrastructure as code

Infrastructure as code: smettere di cliccare e iniziare a governare 🌍

Infrastructure as Code, o IaC, significa definire infrastruttura e configurazioni operative come codice versionato, revisionabile e ripetibile. Traduzione pratica: meno click in console, meno “ma io avevo cambiato solo una regolina”, meno sorprese alle 18:47 del venerdì.

IaC non serve solo a creare VM o cluster. Serve soprattutto a rendere esplicito, ripetibile e verificabile ciò che prima viveva in ticket, screenshot, memoria storica e altri supporti noti alla scienza per essere poco affidabili.

Cosa rientra davvero in IaC 🧱

Con IaC puoi gestire come codice:

  • rete, subnet, security group e firewall
  • cluster, nodi, bilanciatori e storage
  • identità tecniche, ruoli e permessi
  • DNS, certificati e integrazioni cloud
  • policy, tagging, naming convention e guardrail

Il punto non è “scrivere Terraform perché sì”. Il punto è trattare l’infrastruttura con la stessa disciplina che pretendi dal software applicativo.

Ciclo di vita di una modifica IaC 🔄

Quando IaC funziona bene, una modifica infrastrutturale smette di essere un gesto artigianale e diventa un flusso leggibile, revisionabile e ripetibile.

    flowchart LR
  A[Modifica modulo o stack] --> B[Lint e validate]
  B --> C[Plan]
  C --> D[Pull request e review]
  D --> E[Merge]
  E --> F[Apply controllato]
  F --> G[Aggiornamento state remoto]
  G --> H[Drift detection e osservabilità]
  

Se nel tuo processo mancano plan leggibile, review e stato remoto protetto, non stai facendo IaC in modo maturo: stai solo spostando il rischio da una console web a un repository Git.

Modelli principali: dichiarativo vs imperativo ⚖️

Nella pratica trovi due approcci principali:

  • dichiarativo: descrivi lo stato desiderato e il tool calcola come arrivarci
  • imperativo: descrivi i passaggi da eseguire in sequenza

Per provisioning e gestione dello stato, il dichiarativo vince spesso in leggibilità e governance. Per bootstrap, configurazioni puntuali o orchestrazione procedurale, l’imperativo può ancora avere un ruolo. Il trucco è non usare il martello per aprire ogni tipo di vite.

Tool comuni e differenze utili 🛠️

  • Terraform / OpenTofu: standard de facto per provisioning infrastrutturale dichiarativo multi-cloud.
  • Pulumi: approccio IaC tramite linguaggi general purpose, utile quando vuoi composizione più espressiva.
  • Ansible: ottimo per configurazione e automazione operativa, meno ideale come unica fonte di verità per tutto il provisioning cloud.
  • Crossplane: interessante quando vuoi portare modelli IaC dentro ecosistemi Kubernetes.

Scegliere uno strumento giusto è utile. Sceglierlo e poi usarlo senza convenzioni, policy e review è un modo elegante per creare caos versionato.

Vale anche il contrario: passare mesi a discutere il tool “perfetto” mentre il team continua a fare click in console è solo procrastinazione con vocabolario tecnico.

Come separare layer e responsabilità 🏗️

Uno dei modi più efficaci per evitare caos è non buttare tutto nello stesso stack. Un modello semplice e robusto è dividere per layer di responsabilità:

    flowchart TD
  A[Foundation layer] --> B[Platform layer]
  B --> C[Application layer]
  A --> A1[Rete, account, IAM, state backend]
  B --> B1[Cluster, shared services, observability]
  C --> C1[Configurazioni specifiche app e integrazioni]
  

Questa separazione riduce blast radius, chiarisce ownership e impedisce che una modifica applicativa tocchi per sbaglio metà fondazione cloud.

Best practice che fanno la differenza ✅

1. Versiona tutto ciò che conta 📚

Non solo i file principali: anche moduli, policy, variabili condivise, workflow di validazione e documentazione operativa. Se una modifica infrastrutturale è importante ma non è in Git, prima o poi diventerà una storia triste.

2. Separa bene ambienti e responsabilità 🧭

Produzione, staging e sviluppo non dovrebbero differire per magia o memoria orale. Definisci convenzioni chiare per:

  • struttura dei repository
  • naming delle risorse
  • promozione tra ambienti
  • ownership dei moduli
  • confini tra piattaforma e team applicativi

3. Tratta lo state come un asset critico 🗃️

Se usi strumenti con state remoto, proteggilo bene. Locking, backup, cifratura, accesso minimo e audit non sono optional. Perdere o corrompere lo state è un modo molto efficace per trasformare un provisioning in archeologia digitale.

4. Progetta moduli piccoli e leggibili 🧩

Un buon modulo riduce duplicazione e chiarisce le responsabilità. Un modulo gigante che crea mezza regione cloud e 27 eccezioni ambientali è solo monolite con sintassi diversa. Preferisci moduli:

  • con interfacce chiare
  • con input limitati e ben documentati
  • facili da testare
  • facili da versionare e riusare

5. Valida, testa e fai plan review 🧪

IaC senza validazione è solo speranza con estensione diversa. Aggiungi sempre:

  • lint e formattazione
  • validate o check sintattici
  • plan in pull request
  • policy as code
  • test dei moduli dove il tool lo consente

6. Gestisci il drift in modo esplicito 🛰️

Se qualcuno cambia una risorsa a mano, devi saperlo. Il drift va rilevato, analizzato e corretto in modo intenzionale. Non sempre il self-healing automatico è la scelta giusta, ma il drift silenzioso è quasi sempre una pessima idea.

7. Integra IaC con sicurezza e compliance 🔒

IaC è il posto perfetto per codificare controlli ripetibili:

  • cifratura obbligatoria
  • tagging coerente
  • restrizioni di rete
  • limiti di esposizione pubblica
  • vincoli su region, SKU e configurazioni sensibili

8. Progetta una pipeline minima ma rigorosa ⚙️

Non serve una pipeline teatrale con 19 stage solo per sentirsi enterprise. Serve una pipeline sobria che faccia davvero le cose importanti:

  • format e lint
  • validate
  • plan pubblicato in PR
  • controlli di policy e security
  • apply solo su branch o workflow autorizzati
  • audit dei cambiamenti e notifica degli apply

Il valore non sta nel numero di step, ma nella loro affidabilità e nel fatto che siano sempre uguali, anche quando la fretta bussa alla porta.

9. Documenta input, output e assunzioni dei moduli 📝

Molti repository IaC degradano non perché il tool sia scarso, ma perché nessuno capisce più:

  • quali input sono obbligatori
  • quali output sono contratti riusabili
  • quali convenzioni sono richieste
  • quali vincoli di sicurezza o naming sono impliciti

Se un modulo funziona solo “perché lo sa chi l’ha scritto”, non hai standardizzato nulla. Hai solo spostato la dipendenza cognitiva da una console a un file.

IaC, GitOps e CI/CD: chi fa cosa 🔗

La distinzione utile è questa:

  • IaC crea e governa l’infrastruttura
  • CI/CD builda, testa e pubblica artefatti
  • GitOps riconcilia configurazioni e stato desiderato degli ambienti operativi a partire da Git

In molti contesti il flusso migliore è: IaC per cluster, rete, database gestiti e identity; CI/CD per produrre immagini e pacchetti; GitOps per orchestrare la configurazione applicativa e il rollout continuo.

Detto in modo brutale ma utile:

  • IaC crea e protegge il contesto operativo
  • CI/CD produce il software
  • GitOps governa ciò che deve girare dentro quel contesto

Errori comuni da evitare 🚫

Moduli troppo generici o troppo “smart”: se nessuno capisce quali risorse crea davvero, hai perso trasparenza.

State locale condiviso via speranza: se il coordinamento dipende dal fatto che “tanto oggi non lancia nessun altro”, stai già negoziando con il disastro.

Variabili senza governance: naming casuale, default oscuri e override ambientali infiniti sono la via breve verso errori difficili da tracciare.

Mix disordinato di provisioning e configurazione runtime: creare un cluster e installare mezzo mondo dentro lo stesso layer spesso rende tutto più fragile da evolvere.

Nessun controllo in pull request: se il primo momento in cui guardi il piano è dopo l’apply, non è review. È archeologia post-incidente.

In breve 🧾

IaC non è solo un modo più elegante per creare risorse cloud. È un modo per portare disciplina, review, sicurezza e ripetibilità nell’infrastruttura. Se fatto bene, riduce drift, click manuali e dipendenza dalla memoria dei singoli. Se fatto male, produce solo più YAML o più HCL da decifrare alle 2 di notte. Meglio la prima opzione.

Ultimo aggiornamento il