Lavoro con Terraform da un po' di tempo e ho notato che ci sono alcune cose che le persone continuano a chiedermi. Ho pensato che potesse essere utile scrivere un post su alcune delle domande più comuni che ricevo e condividere alcune delle cose imparate lungo il percorso. Questa non è una lista esaustiva, e se hai feedback o suggerimenti, fammelo sapere!
Convenzioni per i File
Terraform offre grande flessibilità nel suo linguaggio di configurazione, rendendo facile scrivere codice e organizzare le directory secondo le proprie preferenze. Questa adattabilità garantisce che il codice rimanga leggibile, scalabile e manutenibile. Una base di codice ben organizzata rende più semplice gestire e scalare l'infrastruttura. Ecco una struttura di file standard che consiglio per iniziare:
- main.tf: Il file principale dove definisci le risorse, le data source e i moduli.
- data.tf: Mi piace mettere qui le data source.
- variables.tf: Dove dichiari tutte le variabili che la tua configurazione utilizzerà.
- outputs.tf: Definisce gli output delle risorse, rendendo i dati disponibili ad altre parti della configurazione.
- provider.tf: I provider vengono inizializzati in questo file.
- versions.tf: Specifica le versioni richieste di Terraform e dei suoi provider.
- terraform.tfvars: Contiene i valori delle variabili che sovrascrivono i valori predefiniti impostati in
variables.tf. Questo file è spesso specifico per ambiente e non dovrebbe essere incluso nel version control.
Convenzioni di Denominazione
La coerenza nella denominazione rende il codice Terraform più facile da leggere e mantenere. Ecco alcune linee guida chiave:
- Usa underscore (
_) al posto dei trattini (-) nei nomi di risorse, data source, variabili e output. - Attieniti a lettere minuscole e numeri.
- Evita di ripetere il tipo di risorsa nel nome. Ad esempio, usa
resource "aws_vpc" "main" {}oresource "aws_vpc" "this" {}invece diresource "aws_vpc" "main_vpc" {}. - Usa sostantivi singolari per i nomi delle risorse.
- Per i valori degli argomenti che saranno esposti agli utenti finali (come i nomi DNS), usa i trattini.
Usare le Data Source
Le data source ti consentono di interrogare risorse esistenti nella tua infrastruttura. Questo può essere incredibilmente potente per recuperare informazioni dinamicamente ed evitare di codificare valori fissi nella configurazione.
Esempio di utilizzo di una data source:
data "aws_ami" "latest" {
most_recent = true
owners = ["self"]
filter {
name = "name"
values = ["my-custom-ami-*"]
}
}
resource "aws_instance" "example" {
ami = data.aws_ami.latest.id
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}Configurare e Gestire lo State
La gestione dello state è un aspetto critico dell'uso efficace di Terraform. Il file di state tiene traccia delle risorse gestite da Terraform, quindi è importante archiviarlo in modo sicuro e renderlo accessibile al team. Ecco alcune best practice:
- Remote State Storage: Usa un backend remoto come AWS S3, Azure Storage o Terraform Cloud per archiviare i file di state. Questo garantisce che lo state non vada perso e possa essere acceduto dai membri del team.
- State Locking: Abilita il locking dello state per evitare che più utenti apportino modifiche concorrenti. AWS S3 con DynamoDB, ad esempio, supporta il locking dello state.
- Non dimenticare di rivedere le risorse periodicamente, limitare l'accesso al file di state e rimuovere con cura le risorse non necessarie.
- Non archiviare mai informazioni sensibili nei file di state o nella configurazione Terraform (usa variabili d'ambiente, data source o uno strumento di secrets management). Ho scritto un intero post su How to Safely Store Secrets in Terraform Using Cloud KMS - dai un'occhiata!
- Non modificare mai i file di state manualmente. Se devi apportare modifiche, usa i comandi Terraform come
terraform state mv,terraform state rmoterraform import(ma se puoi evitarlo, fallo).
Usare i Terraform Workspace
I Terraform workspace sono incredibilmente utili per gestire e isolare diversi file di state all'interno di un unico progetto, specialmente quando si lavora con più ambienti. Ti consentono di distribuire più risorse basandosi su input diversi. Con i workspace, puoi usare la stessa configurazione per vari ambienti come development, staging e production. Ogni workspace mantiene il proprio file di state, rendendo più semplice la gestione di più ambienti in modo efficiente.
I Terraform Workspace sono un ottimo modo per gestire più ambienti (es. dev, staging, production) all'interno della stessa configurazione. I workspace ti consentono di usare un'unica configurazione Terraform per ambienti diversi, con file di state separati per ogni workspace. Dopo aver creato un nuovo workspace con terraform workspace new, puoi passare tra i workspace usando terraform workspace select. Puoi poi fare riferimento al workspace corrente nel tuo codice Terraform per differenziare le configurazioni o i nomi delle risorse, come segue:
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "${terraform.workspace}-example-instance"
}
}Ho scritto un altro post su How to Use Terraform Workspaces to Manage Environment-based Configuration - dai un'occhiata anche a questo!
Strumenti
Terraform offre praticamente tutto il necessario per gestire l'infrastruttura out-of-the-box. Tuttavia, ci sono alcuni strumenti aggiuntivi che possono aiutarti a lavorare in modo più efficiente e a mantenere la qualità del codice.
Usare Formatter e Linter
I formatter sono strumenti che formattano automaticamente il codice secondo una specifica guida di stile. Terraform fornisce il comando terraform fmt per formattare il codice in base alla guida di stile HashiCorp. I linter aiutano a mantenere la qualità del codice applicando le linee guida di stile e individuando potenziali errori. Per mantenere la qualità del codice e la coerenza, puoi usare TFLint come linter. Aiuta a identificare errori e violazioni delle best practice nelle configurazioni Terraform.
Se usi GitHub Actions come pipeline CI/CD (fallo!), puoi usare la terraform-linters/setup-tflint action del marketplace per configurare ed eseguire TFLint nel tuo workflow.
Terratest e Terragrunt
Terratest e Terragrunt sono due strumenti per testare e gestire le configurazioni Terraform. Sono creati da Gruntwork, un'azienda specializzata in DevOps e infrastructure as code.
Terratest è una libreria Go che fornisce pattern e funzioni helper per testare il codice infrastrutturale. Ti consente di scrivere test automatizzati per le configurazioni Terraform per garantire che funzionino come previsto, proprio come testeresti il codice applicativo.
Esempio di un test semplice in Go con Terratest:
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
)
func TestTerraformExample(t *testing.T) {
opts := &terraform.Options{
TerraformDir: "../examples/terraform-aws-example",
}
defer terraform.Destroy(t, opts)
terraform.InitAndApply(t, opts)
}Terragrunt invece è un wrapper leggero per Terraform che fornisce strumenti aggiuntivi per mantenere le configurazioni DRY (Don't Repeat Yourself). È particolarmente utile per gestire più ambienti e gestire le dipendenze tra i moduli.
Conclusione
Ho lavorato con Terraform per un po' di tempo ormai, e lungo il percorso ho imparato alcune cose. Mi ritrovo a menzionare queste best practice e strumenti alle persone nuove a Terraform o che desiderano migliorare i propri workflow esistenti. Spero che questo post ti aiuti a iniziare con Terraform e fornisca alcuni consigli utili per lavorarci in modo efficace!
Seguendo queste best practice per le convenzioni di file e denominazione, usando le data source, configurando e gestendo state e workspace, e sfruttando linter e altri strumenti come Terratest e Terragrunt, garantirai che la tua configurazione infrastructure-as-code sia robusta, manutenibile e scalabile.
Buon Terraforming!
lucavallin

