Cos'è Terraform e a cosa serve
Cos'è Terraform e a cosa serve: infrastructure as code, il file di stato tfstate, plan e apply, provider, moduli, drift e quando invece non ti serve affatto.
Hai creato un server dal pannello del provider cliccando qui e là, poi una regola del firewall, poi un database gestito. Tre mesi dopo devi rifare tutto identico per l'ambiente di test e non ricordi metà delle scelte. In questo articolo trovi cos'è Terraform, come funziona il famigerato file di stato, cosa fanno davvero plan e apply, e — cosa che raramente ti dicono — quando Terraform non ti serve per niente.
Cos'è Terraform
Terraform è uno strumento che descrive l'infrastruttura — server, reti, database, regole del firewall, DNS — in file di testo, e la crea o modifica presso il provider cloud in modo che la realtà corrisponda a quei file.
È l'idea di infrastructure as code: l'infrastruttura smette di essere una serie di clic irripetibili e diventa codice versionato in Git, leggibile, revisionabile in una pull request e ricostruibile da zero.
La differenza con uno script che chiama le API del provider è che Terraform è dichiarativo. Non scrivi "crea un server". Scrivi "deve esistere un server fatto così", e Terraform confronta con quello che c'è: se non esiste lo crea, se esiste ma è diverso lo modifica, se non lo vuoi più lo distrugge.
Il problema che risolve
Tre problemi concreti, in ordine di quanto fanno male:
- Non sai cosa hai. Sei mesi di clic nel pannello e nessuno sa più quali risorse sono attive, quali servono e quali stanno solo generando fattura.
- Non sai riprodurlo. Serve un ambiente di staging identico a quello di produzione, e "identico" fatto a mano non esiste.
- Non sai chi ha cambiato cosa. Qualcosa si è rotto stanotte, e senza uno storico si procede a memoria.
Con Terraform ogni modifica è una modifica a un file, con un autore, una data e un motivo scritto nel messaggio del commit.
Un esempio minimo
La sintassi si chiama HCL:
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.48"
}
}
}
provider "hcloud" {
token = var.hcloud_token
}
variable "hcloud_token" {
type = string
sensitive = true
}
resource "hcloud_server" "web" {
name = "web-prod"
image = "ubuntu-24.04"
server_type = "cx22"
location = "nbg1"
labels = {
ambiente = "produzione"
}
}
output "indirizzo_ip" {
value = hcloud_server.web.ipv4_address
}
I blocchi che userai sempre sono cinque: provider (con chi parlare), resource (cosa deve esistere), variable (i valori che cambiano), output (cosa vuoi sapere alla fine) e data (leggere qualcosa che esiste già senza gestirlo).
Nota sensitive = true sul token: evita che finisca stampato nei log. E il token non si scrive nel file — arriva da una variabile d'ambiente TF_VAR_hcloud_token o da un gestore di segreti.
Lo stato: la cosa più delicata
Qui sta il cuore di Terraform, ed è la parte che causa più disastri.
Terraform deve sapere quale server nel mondo reale corrisponde al blocco hcloud_server.web scritto nel tuo file. Quella corrispondenza la salva in un file chiamato terraform.tfstate: una mappa tra le risorse che hai dichiarato e gli identificativi veri presso il provider.
Se perdi lo stato, Terraform non sa più che quelle risorse sono sue. Al prossimo apply cercherà di creare tutto da capo, mentre l'infrastruttura vera continua a esistere e a costare. Recuperare si può, importando risorsa per risorsa, ma è un lavoro lungo e spiacevole.
Tre regole, e non sono negoziabili:
1. Lo stato non va in Git. Contiene in chiaro le password dei database, le chiavi generate e i token. Nel .gitignore ci vanno *.tfstate, *.tfstate.backup e la cartella .terraform/.
2. Lo stato va su un backend remoto. Sul tuo portatile è un singolo punto di rottura. Su uno spazio di archiviazione condiviso è versionato, cifrato e accessibile al sistema di CI/CD:
terraform {
backend "s3" {
bucket = "azienda-terraform-stati"
key = "produzione/terraform.tfstate"
region = "eu-central-1"
encrypt = true
use_lockfile = true
}
}
3. Serve il lock. Se due persone lanciano apply insieme, lo stato può corrompersi. Il blocco fa aspettare la seconda.
E poi la regola d'oro: una volta che una risorsa è gestita da Terraform, non la tocchi più dal pannello web. Ogni modifica manuale è una bugia che lo stato non conosce.
plan e apply
Il flusso è sempre lo stesso:
terraform init # scarica i provider, configura il backend
terraform fmt # normalizza l'indentazione
terraform validate # controlla la sintassi
terraform plan # mostra cosa cambierebbe, senza cambiare nulla
terraform apply # esegue
terraform destroy # smonta tutto
plan è la funzionalità che rende Terraform accettabile in produzione. Confronta tre cose — quello che hai scritto, quello che dice lo stato e quello che esiste davvero presso il provider — e ti mostra l'elenco delle azioni prima di toccare qualcosa.
L'output usa tre simboli, e vanno letti con attenzione:
| Simbolo | Significato | Attenzione |
|---|---|---|
+ | Crea | Controlla che sia davvero quello che vuoi |
~ | Modifica sul posto | Innocuo nella maggior parte dei casi |
-/+ | Distrugge e ricrea | Il server perde i dati e cambia IP |
- | Distrugge | Definitivo |
La riga da cercare sempre è -/+, cioè forces replacement. Alcuni attributi non sono modificabili sul posto: cambiare il tipo di immagine di un server significa buttarlo via e rifarlo. Un plan letto di fretta è il modo più efficace per cancellare un database in produzione.
In pratica, il pattern serio è salvare il piano e applicare esattamente quello:
terraform plan -out=piano.tfplan
terraform apply piano.tfplan
Così quello che hai revisionato è esattamente quello che viene eseguito, anche se nel frattempo qualcosa è cambiato.
Provider e moduli
I provider sono i plugin che traducono le risorse nelle chiamate API di ciascuna piattaforma: AWS, Azure, Google Cloud, Hetzner, DigitalOcean, Cloudflare, e anche cose non cloud come DNS, GitHub o un cluster Kubernetes.
Qui casca un mito: Terraform non è portabile tra cloud. La sintassi è la stessa, ma le risorse no. Passare da AWS a Google Cloud significa riscrivere tutto, perché aws_instance e google_compute_instance non hanno nulla in comune. Il vantaggio vero è usare un solo linguaggio per piattaforme diverse, non spostarsi tra loro.
I moduli sono cartelle di configurazione riutilizzabili, l'equivalente delle funzioni:
module "server_web" {
source = "./moduli/server"
nome = "web-prod"
tipo = "cx22"
ambiente = "produzione"
}
Un consiglio contro-corrente: non fare moduli subito. Un modulo scritto prima di aver capito cosa varia davvero diventa una scatola con quaranta variabili, più difficile da leggere della duplicazione che voleva eliminare. Scrivi le risorse in chiaro, e quando ti accorgi di ripetere lo stesso blocco per la terza volta, allora estrai.
Il drift
Il drift è la differenza tra quello che i tuoi file dichiarano e quello che c'è davvero. Nasce quando qualcuno apre il pannello del provider e cambia una regola del firewall "solo un attimo, per provare".
Lo scopri con:
terraform plan # segnala anche le differenze non volute
terraform apply -refresh-only
Il problema è che al prossimo apply Terraform riporterà tutto a come dice il codice, cancellando quella modifica manuale — magari quella che teneva in piedi il sito. Il drift non è un difetto di Terraform: è il costo di avere due fonti di verità.
Il rimedio è organizzativo più che tecnico: togliere i permessi di scrittura nel pannello, far passare le modifiche solo dalla pipeline, ed eseguire un plan programmato che avvisi quando qualcosa si discosta.
Cosa Terraform non fa
Terraform crea il server. Non lo configura dentro. Non installa pacchetti, non scrive file di configurazione, non gestisce i servizi.
Quel lavoro è di altri strumenti: Ansible, uno script di cloud-init al primo avvio, o dei container. Vederli come concorrenti è un errore frequente: Terraform prepara la macchina e la rete, poi qualcos'altro ci mette sopra il software. La configurazione manuale è raccontata in configurare un VPS da zero, e il modo moderno di distribuire l'applicazione è in cos'è Docker.
Quando NON ti serve
Questa sezione è la più utile dell'articolo, perché Terraform è spesso adottato prima del tempo.
Se hai un VPS solo, non ti serve. Scrivere venti righe di HCL, gestire un backend remoto e ricordarsi il flusso plan/apply per una macchina che hai creato una volta e non toccherai più è puro costo. Ti basta un documento con scritto cosa hai comprato e come è configurato.
Non ti serve nemmeno quando:
- L'infrastruttura è completamente gestita da un servizio tipo Vercel o Netlify, dove non ci sono server da creare.
- Sei da solo su un progetto piccolo che non cambia mai. Terraform paga sulle modifiche ripetute, non sulla creazione iniziale.
- Stai prototipando, nella fase in cui distruggi e ricrei dieci volte al giorno.
Inizia a convenire quando gli ambienti sono più di uno, le persone che toccano l'infrastruttura sono più di una, le risorse sono più di una decina, oppure devi poter dimostrare chi ha cambiato cosa e quando.
Tre errori che fanno perdere ore (o soldi)
Lo stato committato in Git. Le credenziali del database finiscono nella cronologia del repository, e la cronologia non si dimentica: vanno cambiate tutte.
apply senza leggere il plan. Terraform ti dice esattamente cosa sta per distruggere. Il conteggio finale Plan: 2 to add, 1 to change, 3 to destroy va letto ogni volta, soprattutto il terzo numero.
Nessun vincolo di versione sui provider. Senza version = "~> 1.48", un terraform init fatto sei mesi dopo scarica una versione maggiore con comportamenti diversi, e ti ritrovi un piano che vuole ricreare risorse che non hai toccato. Il file .terraform.lock.hcl va commesso in Git proprio per questo.
In sintesi
Terraform descrive l'infrastruttura in file di testo e la porta a corrispondere a quella descrizione, rendendola versionata, revisionabile e riproducibile.
Il file di stato è la parte fragile: mai in Git, sempre su un backend remoto con lock, e nessuna modifica manuale dal pannello alle risorse che gestisce.
plan prima di apply, sempre, cercando i -/+ che distruggono e ricreano invece di modificare.
Non è portabile tra cloud e non configura il software dentro le macchine: fa una cosa sola, la creazione e la modifica delle risorse.
E se hai un VPS solo, lasciala perdere. Terraform ripaga quando gli ambienti e le persone sono più di uno; prima di allora è solo un livello in più tra te e il lavoro.
Per il quadro generale delle piattaforme su cui lo useresti, vedi cos'è il cloud computing; per il pezzo che automatizza l'esecuzione di plan e apply a ogni modifica, cos'è la CI/CD.