Introduzione a Terraform e al provider Azure
Terraform è uno strumento open source di HashiCorp che permette di creare e modificare infrastrutture cloud tramite file di configurazione scritti in HCL (HashiCorp Configuration Language). Dal 2023 è distribuito con licenza BUSL; chi vuole una licenza puramente open source può usare il fork OpenTofu, sostanzialmente compatibile.
Il principio è semplice: voi descrivete in un file .tf lo stato desiderato dell’infrastruttura e Terraform calcola autonomamente quali operazioni eseguire per allineare il cloud a quella descrizione. Non dovete dire come fare, ma cosa volete: questo è l’approccio dichiarativo, ed è la differenza fondamentale rispetto agli script imperativi (Bash, PowerShell, Azure CLI usata in modo procedurale). Una conseguenza diretta è l’idempotenza: se eseguite apply due volte di fila senza modifiche, la seconda esecuzione non fa nulla.
Perché scegliere Terraform per IaC
Azure offre nativamente ARM Template e Bicep, ottimi prodotti ma limitati al solo ecosistema Microsoft. Le ragioni per cui molte organizzazioni scelgono comunque Terraform sono le seguenti.
Multi-cloud e multi-provider
Terraform supporta oltre 4.000 provider ufficiali e community: Azure, AWS, GCP, Kubernetes, GitHub, Cloudflare, vSphere e molti altri. Una stessa configurazione può orchestrare risorse eterogenee, ad esempio creare una VM su Azure e configurare il DNS su Cloudflare in un unico apply.
Pianificazione esplicita delle modifiche
Il comando terraform plan mostra in anticipo quali risorse verranno create, modificate o distrutte. Questo permette code review approfondite e riduce drasticamente il rischio di sorprese in produzione.
Stato come fonte di verità
Terraform mantiene un file di stato che mappa le risorse del codice agli oggetti reali sul cloud. Questo permette di rilevare drift (modifiche manuali fuori da Terraform), gestire dipendenze e supportare workflow di team tramite backend remoti.
Ecosistema e comunità
Il Terraform Registry pubblico contiene migliaia di moduli pronti all’uso. Per Azure esistono moduli verificati ufficialmente (Azure Verified Modules) che incapsulano best practice di sicurezza e naming.
Quando NON scegliere Terraform
Per onestà: progetti puramente Azure-only di piccole dimensioni possono trarre vantaggio dall’integrazione più stretta di Bicep, soprattutto per le API in anteprima. Se serve scrivere logica complessa in un linguaggio di programmazione completo, Pulumi (TypeScript/Python/Go) può essere preferibile.
Cosa è un provider Terraform
Un provider è un plugin che insegna a Terraform come parlare con una specifica API. Terraform di per sé non sa nulla di Azure o di altri sistemi: la conoscenza del cloud target è incapsulata nei provider, scaricati dal Registry quando si esegue terraform init.
Ogni provider espone due tipi di entità:
- Resource: un oggetto gestito da Terraform, ad esempio azurerm_resource_group o azurerm_virtual_network. Terraform ne gestisce l’intero ciclo di vita.
- Data source: un oggetto in sola lettura, per recuperare informazioni da risorse esistenti non gestite da Terraform.
I provider per Azure
Per Azure esistono tre provider ufficiali HashiCorp:
- azurerm: il provider principale, copre la stragrande maggioranza dei servizi Azure Resource Manager.
- azapi: chiama direttamente le API REST di Azure, utile per accedere a risorse o proprietà ancora in anteprima e non coperte da azurerm.
- azuread: dedicato a Microsoft Entra ID per gestire utenti, gruppi, app registration e service principal.
Versionamento dei provider
I provider sono versionati indipendentemente dal core di Terraform. Al momento la versione corrente è Terraform 1.15.x e azurerm è alla 4.71, in avvicinamento alla 5.0. È fortemente raccomandato fissare le versioni nel blocco required_providers per evitare breaking change inattesi.
Configurazione e registrazione del provider Azure
La configurazione del provider azurerm avviene su due livelli distinti, da non confondere:
- La dichiarazione del provider nel codice Terraform: indica quale provider usare e con quali opzioni.
- La registrazione dei Resource Provider Azure sulla sottoscrizione: abilita i namespace di risorse (Microsoft.Compute, Microsoft.Network, ecc.). Senza questa, le API rifiutano la creazione delle risorse.
Dichiarazione del provider nel codice
La dichiarazione minima in un file provider.tf:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
terraform { required_version = ">= 1.5.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 4.0" } } } provider "azurerm" { features {} subscription_id = var.subscription_id } |
Il blocco features {} è obbligatorio anche se vuoto: serve a configurare comportamenti specifici di alcune risorse. L’operatore ~> 4.0 significa “qualsiasi 4.x.x ma non la 5.0”.
Registrazione dei Resource Provider su Azure
Azure è organizzato in Resource Provider (da non confondere con i provider Terraform): Microsoft.Compute, Microsoft.Network, Microsoft.Storage, ecc. Prima di creare risorse di un certo tipo, il relativo Resource Provider deve essere registrato sulla sottoscrizione.
Storicamente azurerm registrava in automatico circa 68 Resource Provider; oggi il comportamento è configurabile tramite resource_provider_registrations:
|
1 2 3 4 5 6 |
provider "azurerm" { features {} resource_provider_registrations = "core" # Valori: "core" (default 4.x), "extended", "all", "none" } |
Dalla 5.0 il default sarà none. Se l’identità Terraform non ha i permessi di registrazione, impostate none e registrate manualmente con Azure CLI:
|
1 2 |
az provider register --namespace Microsoft.Network |
La registrazione si può fare anche dal portale Azure, da Sottoscrizione → Resource providers. Nell’esempio sotto registriamo Microsoft.AzureTerraform, il Resource Provider che espone i servizi gestiti Terraform su Azure. Lo stato iniziale è NotRegistered:

Figura 1: Resource Provider Microsoft.AzureTerraform prima della registrazione
Cliccando su Register (oppure eseguendo az provider register –namespace Microsoft.AzureTerraform) lo stato passa a Registered:

Figura 2: Resource Provider Microsoft.AzureTerraform dopo la registrazione
Autenticazione del provider
Il provider azurerm supporta diverse modalità di autenticazione:
- Azure CLI: ideale per uso interattivo locale, con az login.
- Service Principal: per pipeline CI/CD non interattive (Azure DevOps, GitHub Actions).
- Managed Identity: quando Terraform gira da una VM Azure o da un container con identità assegnata.
- OIDC / Workload Identity Federation: metodo moderno raccomandato per pipeline GitHub e GitLab, evita segreti long-lived.
Per iniziare basta:
|
1 2 3 4 |
az login az account set --subscription "<subscription-id>" |
I comandi principali
terraform init
Primo comando in un nuovo progetto. Scarica provider e moduli, inizializza il backend e crea il file .terraform.lock.hcl che blocca le versioni esatte. Il file di lock va versionato in Git.
|
1 2 |
terraform init |
terraform fmt e terraform validate
fmt riformatta i file .tf secondo lo stile canonico; validate verifica che la configurazione sia sintatticamente corretta. Entrambi sono velocissimi e ideali nei controlli pre-commit.
|
1 2 3 4 |
terraform fmt -recursive terraform validate |
terraform plan
Mostra il piano di esecuzione confrontando codice e stato. I simboli sono + (crea), – (distrugge), ~ (modifica in-place), -/+ (ricrea).
|
1 2 |
terraform plan |
Buona pratica: salvare il piano su file con terraform plan -out=tfplan e applicarlo con terraform apply tfplan, per evitare modifiche tra plan e apply.
terraform apply
Esegue le modifiche. Senza argomenti chiede conferma interattiva; con un file di piano salvato la salta.
|
1 2 3 4 |
terraform apply terraform apply -auto-approve |
terraform destroy
Distrugge tutte le risorse del progetto. Utile in test e sandbox, estremamente pericoloso in produzione. Valutate prevent_destroy sulle risorse critiche.
|
1 2 |
terraform destroy |
terraform output e terraform state
output mostra i valori esposti dal modulo radice (utile in pipeline con il flag -json). I sotto-comandi state list, state show, state mv e state rm servono a ispezionare e manipolare lo stato senza modificare le risorse reali.
|
1 2 3 4 |
terraform output terraform state list |
Cosa è lo state e perché è cruciale
Lo state è il cuore di Terraform: un file JSON (di default terraform.tfstate) che mappa le risorse dichiarate nel codice agli ID reali sul cloud. Senza state, Terraform non saprebbe associare un blocco resource a una specifica risorsa Azure.
Lo state memorizza ID univoco, attributi computati, dipendenze e metadati del provider. È fondamentale per quattro motivi: performance, mappatura tra codice e risorse reali, rilevamento del drift e gestione delle dipendenze.
State locale vs state remoto
Per default lo state è salvato su disco locale. Per progetti in team non va bene: niente locking, niente condivisione e soprattutto contiene segreti in chiaro (password, chiavi, connection string), quindi non deve mai essere committato in Git. La soluzione standard è il backend remoto. Su Azure il backend nativo è azurerm, che salva lo state in un container Storage Account con locking via blob lease:
|
1 2 3 4 5 6 7 8 9 |
terraform { backend "azurerm" { resource_group_name = "rg-tfstate" storage_account_name = "sttfstateprod001" container_name = "tfstate" key = "prod/network.tfstate" } } |
Alternative: HCP Terraform, Spacelift, env0.
Best practice per lo state
- Backend remoto fin dal primo giorno per progetti in team o produzione.
- Versioning attivo sul container Storage Account che ospita lo state.
- Permessi restrittivi: chi accede allo state accede ai segreti delle risorse.
- Mai modificare lo state a mano: usate terraform state. Suddividete progetti grandi in più state separati. Aggiungete terraform.tfstate*e .terraform/ al .gitignore.
Conclusioni
Avete visto cos’è Terraform, perché conviene adottarlo, come funzionano i provider Azure, i comandi del flusso di lavoro e perché lo state è il componente più delicato. Sono le basi indispensabili per affrontare le prossime guide pratiche. Il consiglio è di non limitarvi alla lettura: installate Terraform, autenticatevi su una sottoscrizione di test e provate i comandi su un piccolo progetto.
Per approfondimenti
- Documentazione Terraform: https://developer.hashicorp.com/terraform/docs
- Provider azurerm: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
- Linguaggio HCL: https://developer.hashicorp.com/terraform/language
- Azure Verified Modules: https://azure.github.io/Azure-Verified-Modules/