Infrastructure as Code per PMI: da provisioning manuale a playbook Ansible e moduli Terraform ripetibili

Infrastructure as Code per PMI: da provisioning manuale a playbook Ansible e moduli Terraform ripetibili

In un progetto per un'azienda del settore servizi digitali, il provisioning di un nuovo server di staging richiedeva 4 ore di lavoro manuale: installazione pacchetti, configurazione Nginx, setup PHP-FPM, hardening SSH, certificati TLS, regole firewall. Ogni server era leggermente diverso dagli altri - quello che il Visible Ops Handbook chiama "snowflake server". Gartner stima che l'80% dei downtime non pianificati è causato da errori di processo e configurazione, non da guasti hardware. Infrastructure as Code elimina questa classe di problemi alla radice: l'infrastruttura è definita in file versionabili, eseguibili e ripetibili.

Cos'è Infrastructure as Code e perché NSA e CISA la raccomandano?

Infrastructure as Code significa gestire server, reti e servizi tramite file di configurazione dichiarativi invece che tramite procedure manuali. AWS la definisce come "applicare lo stesso rigore dello sviluppo applicativo al provisioning dell'infrastruttura: tutte le configurazioni devono essere definite in modo dichiarativo e versionate in un sistema di source control."

Nel marzo 2024, NSA e CISA hanno pubblicato le Top Ten Cloud Security Mitigation Strategies, dedicando un intero Cybersecurity Information Sheet a IaC. Le raccomandazioni chiave: abilitare version control sui template IaC, evitare modifiche manuali alle risorse deployate via IaC, abilitare logging continuo per rilevare cambiamenti non autorizzati, usare policy-as-code per gestione permessi e drift detection.

Il DORA Report 2024 conferma la correlazione: i team elite (19% del campione) deployano 182× più frequentemente dei team low-performing, con un change failure rate 8× inferiore e un recovery time 2.293× più rapido. La differenza principale è l'automazione - e IaC è il fondamento dell'automazione infrastrutturale.

Come implementare IaC in una PMI partendo da Ansible e Terraform?

I due strumenti coprono casi d'uso complementari: Terraform per il provisioning (creare VPS, reti, database - l'infrastruttura stessa), Ansible per la configurazione (installare pacchetti, configurare servizi, deployare applicazioni). Terraform è dichiarativo con state file; Ansible è task-based e agentless (connessione via SSH, nessun daemon sui nodi gestiti). Per una PMI con 3-15 server, Ansible da solo copre la maggior parte dei casi - il provisioning dei VPS avviene raramente e può restare manuale, mentre la configurazione cambia ad ogni deploy:

---
## playbook-lemp.yml - Setup server LEMP con hardening base
- name: Provisioning server LEMP
  hosts: staging
  become: true
  vars:
    php_version: "8.3"
    domain: "staging.example.com"

  tasks:
    - name: Aggiorna pacchetti e installa dipendenze
      apt:
        update_cache: yes
        name:
          - nginx
          - "php{{ php_version }}-fpm"
          - "php{{ php_version }}-mysql"
          - "php{{ php_version }}-mbstring"
          - "php{{ php_version }}-xml"
          - certbot
          - python3-certbot-nginx
          - ufw
        state: present

    - name: Configura Nginx per il dominio
      template:
        src: templates/nginx-site.conf.j2
        dest: "/etc/nginx/sites-available/{{ domain }}"
      notify: Reload Nginx

    - name: Abilita il sito e rimuovi default
      file:
        src: "/etc/nginx/sites-available/{{ domain }}"
        dest: "/etc/nginx/sites-enabled/{{ domain }}"
        state: link

    - name: Hardening SSH - disabilita accesso root e password auth
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "{{ item.regexp }}"
        line: "{{ item.line }}"
      loop:
        - { regexp: '^PermitRootLogin', line: 'PermitRootLogin no' }
        - { regexp: '^PasswordAuthentication', line: 'PasswordAuthentication no' }
      notify: Restart SSH

    - name: Configura UFW - solo SSH, HTTP, HTTPS
      ufw:
        rule: allow
        port: "{{ item }}"
      loop: ['22', '80', '443']

    - name: Attiva UFW con policy deny di default
      ufw:
        state: enabled
        policy: deny

  handlers:
    - name: Reload Nginx
      service: name=nginx state=reloaded
    - name: Restart SSH
      service: name=sshd state=restarted

Il playbook è idempotente - eseguirlo due volte produce lo stesso risultato senza effetti collaterali. Ogni modifica al file è tracciata in Git: chi ha cambiato cosa, quando, e perché. Il report Firefly State of IaC 2025 mostra che l'89% delle organizzazioni ha adottato IaC, ma solo il 6% ha codificato il 100% dell'infrastruttura - il 40% riporta che correggere il configuration drift richiede da giorni a settimane. Il playbook sopra, eseguito con ansible-playbook -i inventory.yml playbook-lemp.yml, elimina il drift in minuti.

Errori comuni nell'adozione di Infrastructure as Code

Il primo errore è adottare Terraform per infrastrutture che non cambiano. Una PMI con 5 server stabili non ha bisogno di state file, moduli HCL e backend remoti - Ansible con un inventory YAML e playbook per la configurazione è sufficiente. Terraform diventa necessario quando l'infrastruttura è dinamica (auto-scaling, ambienti effimeri, multi-cloud) o quando il provisioning stesso deve essere ripetibile (disaster recovery, ambienti di test identici alla produzione).

Il secondo è non versionare l'inventory. I playbook sono in Git, ma l'inventory (l'elenco dei server con IP, ruoli e variabili) resta spesso in un file locale non versionato. Un inventory perso significa non sapere più quale playbook applicare a quale server. L'inventory deve essere in Git accanto ai playbook, con i segreti (password, chiavi API) gestiti via ansible-vault - mai in chiaro nel repository.

Il terzo è ignorare il configuration drift dopo il deploy iniziale. Un playbook eseguito una volta e mai più lascia i server liberi di divergere: un apt upgrade manuale su un server, una modifica a php.ini su un altro. La soluzione è eseguire i playbook periodicamente (cron o CI/CD pipeline) in modalità check-first (--check --diff) per rilevare drift, e in modalità apply per correggerlo.

Il quarto è non testare i playbook prima della produzione. Molecule (il framework di test per Ansible) permette di eseguire i playbook in container Docker, verificare l'idempotenza (due esecuzioni consecutive senza cambiamenti), e validare il risultato con assertion. Senza test, un playbook con un errore di sintassi può lasciare un server in stato inconsistente - esattamente il problema che IaC doveva risolvere.

Infrastructure as Code trasforma l'infrastruttura da conoscenza tacita (nella testa del sysadmin) a conoscenza codificata (nel repository). L'hardening dei server diventa un playbook ripetibile invece di una procedura manuale, e ogni modifica passa per code review prima di toccare la produzione. Per conoscere il mio approccio all'automazione infrastrutturale, visita la mia pagina professionale. Se la tua infrastruttura dipende da procedure manuali che solo una persona conosce, contattami per una consulenza dedicata - partiamo dall'inventario dei server e dalla codifica delle configurazioni in playbook versionabili.

Ultima modifica: