Sägetstrasse 18, 3123 Belp, Switzerland +41 79 173 36 84 info@ict.technology

    Terraform @Scale - Parte 3b: Strategie di recupero dal Blast Radius

    Nonostante un'attenta minimizzazione del blast radius, la segmentazione degli state e l’uso di lifecycle guardrails, può prima o poi succedere: un terraform apply elimina per errore risorse produttive - oppure un terraform destroy colpisce più di quanto previsto.

    Cosa fare quando il danno è ormai fatto?

    Nell’ultimo articolo di questa serie ho spiegato come minimizzare il blast radius. In questa continuazione mostro tecniche comprovate per il ripristino di Terraform State danneggiati e per la limitazione dei danni dopo un incidente.

    1. Primo soccorso a cuore aperto: State Surgery

    Quando le risorse esistono ancora fisicamente ma non sono più correttamente referenziate nello state file, non resta che un intervento chirurgico da riga di comando. La cosiddetta State Surgery consente di ripulire manualmente i Terraform State e riallinearli alla realtà. Terraform at scale 8b

    ⚠️ Importante: Questo approccio richiede una comprensione approfondita della logica di Terraform e dello stato reale dell'infrastruttura. È potente, ma anche pericoloso se usato con leggerezza. Per questo motivo, creare sempre un backup completo dello state file attuale prima di apportare modifiche manuali!

    È possibile salvare lo state attuale con il seguente comando CLI:


    $> terraform state pull > state-backup-$(date +%Y%m%d-%H%M%S).json
    

     Successivamente, è possibile rimuovere risorse specifiche dallo state senza eliminare la risorsa cloud corrispondente. In questo esempio, la risorsa interessata si chiama aws_instance.problematic_instance:


    $> terraform state rm aws_instance.problematic_instance

    Ora creare nel proprio manifest Terraform una nuova risorsa per rappresentare la risorsa recuperata (in questo esempio si usa il nome aws_instance.recovered_instance). Può trattarsi di una risorsa completamente vuota oppure di un copia e incolla completo della vecchia risorsa, a seconda del tipo di danneggiamento.
    In seguito, importare la risorsa interessata tramite il suo ID univoco (nell’esempio i-1234567890abcdef0) con il nuovo nome:


    $> terraform import aws_instance.recovered_instance i-1234567890abcdef0
    

     In alternativa, è possibile spostare una risorsa esistente nel nuovo state in una nuova posizione. Questa può trovarsi in un'altra parte dell'infrastruttura oppure in un altro modulo Terraform:


    $> terraform state mv aws_instance.misplaced_resource aws_instance.correct_scope

     

    2. Ricostruzione graduale: Strategie di Partial Import

    In scenari complessi – ad esempio dopo un malfunzionamento parziale in uno state di grandi dimensioni – un semplice import non è sufficiente. In questi casi è consigliabile un ripristino strutturato e graduale tramite Partial Import Configurations (disponibile da Terraform 1.5).

    Procedura

    a. Identificare le risorse coinvolte tramite -detailed-exitcode

    $> terraform plan -detailed-exitcode

    Il comando terraform plan -detailed-exitcode è una variante specifica del comando standard terraform plan. Restituisce codici di uscita più dettagliati, il che è particolarmente utile nelle pipeline di automazione e CI/CD.

    Funzionamento:

    • terraform plan mostra normalmente quali modifiche Terraform apporterebbe all'infrastruttura, senza effettuare cambiamenti reali.
    • Con il flag -detailed-exitcode cambia il comportamento dei codici di uscita, rendendo il risultato del piano più preciso:
    Exit-CodeSignificato
    0 Nessuna modifica; l'infrastruttura è conforme alla configurazione.
    1 Si è verificato un errore (es. errore di sintassi, errore del provider, ecc.).
    2 Modifiche previste; il piano proposto modificherebbe l'infrastruttura.

     

    Nota: Un exit code 2 indica risorse modificate. Queste richiedono quindi particolare attenzione.

    Questa funzione non è sempre menzionata nei tutorial più semplici, ma è molto diffusa nei team che automatizzano i workflow Terraform e garantisce cambiamenti infrastrutturali robusti e prevedibili.

    b. Definire la configurazione per l'import

    Creare ora una configurazione per le risorse interessate:


    import {
      to = aws_vpc.recovered_vpc
      id = "vpc-12345678"
    }
    
    import {
      to = aws_subnet.recovered_subnet[0]
      id = "subnet-12345678"
    }

    c. Eseguire l'import automatico e la generazione della configurazione tramite -generate-config-out

    Il comando terraform plan -generate-config-out=<file> è una funzionalità sperimentale introdotta con Terraform v1.5. Permette di generare file di configurazione Terraform (in formato HCL) per risorse definite nei blocchi import, ma che non sono ancora presenti nella configurazione.

    Questa funzione è particolarmente utile quando si desidera importare infrastruttura esistente in Terraform, poiché aiuta a generare il codice di configurazione necessario sulla base dello stato reale delle risorse.


    $> terraform plan -generate-config-out=generated.tf
    [...] $> terraform apply

     Terraform esegue le seguenti operazioni:

    • Analizza i blocchi import presenti nella configurazione.
    • Per ogni risorsa da importare che non ha ancora una configurazione, Terraform genera un blocco HCL con una selezione di argomenti e valori il più possibile corrispondenti alla realtà.
    • La configurazione generata viene scritta nel file indicato (in questo esempio generated.tf). È necessario fornire un nuovo percorso di file; l’uso di un file esistente genera un errore.
    • Dopo l’esecuzione del comando, Terraform mostra il piano per l’import delle risorse e indica dove è stata salvata la configurazione generata.

    terraform plan -generate-config-out=<file> è uno strumento potente e sperimentale per generare configurazioni Terraform a partire da risorse esistenti definite in blocchi import. Facilita l’integrazione di infrastruttura non ancora gestita in Terraform. Verificare sempre il codice generato e adattarlo prima dell’uso.

    d. Verifica della realtà: riconciliazione dello state con -refresh-only e -refresh=true

    Terraform at scale 8dQuando il Terraform State è divergente dalla realtà, ma non mancano risorse, un confronto tra lo state e l'infrastruttura reale può essere d’aiuto. Questo cosiddetto Refresh può rilevare e in certi casi correggere automaticamente le deviazioni.


    # Refresh dello state senza modifiche
    $> terraform apply -refresh-only
    
    # Confronto tra state e infrastruttura reale
    $> terraform plan -refresh=true

    Il comando terraform plan -refresh=true genera un piano di esecuzione per l’infrastruttura gestita da Terraform, con l’istruzione esplicita di aggiornare lo stato prima della pianificazione (refresh).

    Dettagli del comportamento

    • Di default, terraform plan aggiorna automaticamente lo state file per allinearlo con l'infrastruttura reale prima di verificare modifiche.
    • Con il flag -refresh=true si impone esplicitamente a Terraform di eseguire questo aggiornamento. È generalmente ridondante, poiché già comportamento predefinito, ma assicura che tutte le modifiche esterne (es. tramite console cloud) siano rilevate e visualizzate nel piano.
    • Durante il refresh, Terraform interroga tutte le risorse gestite per aggiornare lo stato corrente. Confronta poi questo stato aggiornato con i file di configurazione per indicare quali azioni (aggiunta, modifica, eliminazione) sono necessarie per allineare la realtà alla configurazione desiderata.

    Confronto con -refresh=false

    OpzioneComportamento
    -refresh=true Lo stato viene aggiornato con l'infrastruttura reale prima della pianificazione (comportamento predefinito).
    -refresh=false L’aggiornamento dello stato viene saltato, il che può velocizzare la pianificazione ma ignora modifiche esterne.

     

    e. Drift Detection in ambienti scriptati con -detailed-exitcode

    Il comando terraform plan -detailed-exitcode viene utilizzato per generare un piano di esecuzione in Terraform, con un comportamento speciale riguardo ai codici di uscita (exit code). Questa tecnica è ideale per l’utilizzo in pipeline CI/CD o come controllo preventivo prima di un terraform apply in produzione.


    #!/bin/bash
    terraform plan -detailed-exitcode
    if [ $? -eq 2 ]; then
        echo "Configuration drift detected – manual review required"
    fi

    Spiegazione degli Exit Code

    Quando si esegue terraform plan -detailed-exitcode, Terraform:

    • Mostra le azioni pianificate (aggiunte, modifiche, eliminazioni) necessarie per allineare l’infrastruttura alla configurazione, senza apportare modifiche reali.
    • Restituisce un exit code specifico in base al risultato del piano:
    Exit CodeSignificato
    0 Nessuna modifica; l'infrastruttura è conforme alla configurazione.
    1 Si è verificato un errore (es. errore di sintassi, problema con il provider).
    2 Ci sono modifiche da applicare (risorse aggiunte, modificate o eliminate).

     

    Conclusione

    Come avete potuto vedere in questo articolo, anche un terraform destroy che sfugge di mano, nonostante tutte le precauzioni, non è la fine del mondo.
    Anzi, nell’era IT pre-Terraform, l’impatto era spesso molto più grave, poiché mancavano strumenti come quelli integrati in Terraform. All’epoca si diceva: “Ora siamo offline, ricostruiamo il servizio manualmente da zero in 1-2 giorni, e poi vediamo cosa è andato storto”.

    È però anche vero che, anche con Terraform, il ripristino di stati operativi corrotti (State) e di risorse mal configurate o distrutte rimane un compito tecnicamente complesso che richiede competenze esperte.

    Nella prossima parte di questa serie di articoli vedremo quindi quali strumenti offre Terraform per individuare e prevenire precocemente i rischi derivanti da un blast radius troppo ampio.