Best practice per stile e struttura generali

Questo documento fornisce suggerimenti di base su stile e struttura per le configurazioni Terraform. Questi consigli si applicano ai moduli Terraform riutilizzabili e alle configurazioni principali.

Questa guida non è un'introduzione a Terraform. Per un'introduzione all'utilizzo di Terraform con Google Cloud, consulta Introduzione a Terraform.

Segui una struttura del modulo standard

  • I moduli Terraform devono seguire la struttura del modulo standard.
  • Inizia ogni modulo con un file main.tf, dove le risorse si trovano per impostazione predefinita.
  • In ogni modulo, includi un file README.md in formato Markdown. Nel README.md file, includi la documentazione di base sul modulo.
  • Inserisci gli esempi in una cartella examples/, con una sottodirectory separata per ogni esempio. Per ogni esempio, includi un file README.md dettagliato.
  • Crea raggruppamenti logici di risorse con i relativi file e nomi descrittivi, ad esempio network.tf, instances.tf o loadbalancer.tf.
    • Evita di assegnare a ogni risorsa un proprio file. Raggruppa le risorse in base alla loro finalità condivisa. Ad esempio, combina google_dns_managed_zone e google_dns_record_set in dns.tf.
  • Nella directory principale del modulo, includi solo i file Terraform (*.tf) e dei metadati del repository (ad esempio README.md e CHANGELOG.md).
  • Inserisci la documentazione aggiuntiva in una sottodirectory docs/.

Adotta una convenzione di denominazione

  • Assegna un nome a tutti gli oggetti di configurazione utilizzando gli underscore per delimitare più parole. Questa pratica garantisce la coerenza con la convenzione di denominazione per i tipi di risorse, i tipi di origini dati e altri valori predefiniti. Questa convention non si applica ai nomi degli argomenti.

    Consigliato:

    resource "google_compute_instance" "web_server" {
      name = "web-server"
    }
    

    Non consigliato:

    resource "google_compute_instance" "web-server" {
      name = "web-server"
    }
    
  • Per semplificare i riferimenti a una risorsa che è l'unica del suo tipo (ad esempio, un singolo bilanciatore del carico per un intero modulo), assegna alla risorsa il nome main.

    • È necessario un maggiore impegno mentale per ricordare some_google_resource.my_special_resource.id rispetto a some_google_resource.main.id.
  • Per distinguere le risorse dello stesso tipo (ad es.primary e secondary), fornisci nomi significativi.

  • Assegna nomi singolari alle risorse.

  • Nel nome della risorsa, non ripetere il tipo di risorsa. Ad esempio:

    Consigliato:

    resource "google_compute_global_address" "main" { ... }
    

    Non consigliato:

    resource "google_compute_global_address" "main_global_address" { … }
    

Utilizza le variabili con attenzione

  • Dichiara tutte le variabili in variables.tf.
  • Assegna alle variabili nomi descrittivi pertinenti al loro utilizzo o scopo:
    • Gli input, le variabili locali e gli output che rappresentano valori numerici, come le dimensioni del disco o della RAM, devono essere denominati con le unità di misura (ad esempio ram_size_gb). Google Cloud Le API non hanno unità di misura standard, pertanto la denominazione delle variabili con le unità di misura rende chiara l'unità di input prevista per i gestori della configurazione.
    • Per le unità di archiviazione, utilizza i prefissi delle unità binarie (potenze di 1024): kibi, mebi, gibi. Per tutte le altre unità di misura, utilizza i prefissi delle unità decimali (potenze di 1000): kilo, mega, giga. Questo utilizzo corrisponde a quello all'interno di Google Cloud.
    • Per semplificare la logica condizionale, assegna alle variabili booleane nomi positivi, ad esempio enable_external_access.
  • Le variabili devono avere descrizioni. Le descrizioni vengono incluse automaticamente nella documentazione generata automaticamente di un modulo pubblicato. Le descrizioni aggiungono un contesto aggiuntivo per i nuovi sviluppatori che i nomi descrittivi non possono fornire.
  • Assegna alle variabili tipi definiti.
  • Se opportuno, fornisci i valori predefiniti:
    • Per le variabili con valori indipendenti dall'ambiente (ad esempio la dimensione del disco), fornisci valori predefiniti.
    • Per le variabili con valori specifici per l'ambiente (ad esempio project_id), non fornire valori predefiniti. In questo modo, il modulo di chiamata deve fornire valori significativi.
  • Utilizza valori predefiniti vuoti per le variabili (ad esempio stringhe o elenchi vuoti) solo se lasciare la variabile vuota è una preferenza valida che le API sottostanti non rifiutano.
  • Usa le variabili con giudizio. Parametrizza solo i valori che devono variare per ogni istanza o ambiente. Quando decidi se esporre una variabile, assicurati di avere un caso d'uso concreto per modificarla. Se esiste solo una piccola possibilità che una variabile possa essere necessaria, non esporla.
    • L'aggiunta di una variabile con un valore predefinito è compatibile con le versioni precedenti.
    • La rimozione di una variabile non è compatibile con le versioni precedenti.
    • Se un valore letterale viene riutilizzato in più posizioni, puoi utilizzare un valore locale senza esporlo come variabile.

Esporre gli output

  • Organizza tutti gli output in un file outputs.tf.
  • Fornisci descrizioni significative per tutti gli output.
  • Documenta le descrizioni dell'output nel file README.md. Genera automaticamente le descrizioni al commit con strumenti come terraform-docs.
  • Stampa tutti i valori utili a cui i moduli principali potrebbero dover fare riferimento o che potrebbero dover condividere. Soprattutto per i moduli open source o molto utilizzati, esponi tutte le uscite che hanno potenziale di utilizzo.
  • Non passare gli output direttamente tramite le variabili di input, perché ciò impedisce che vengano aggiunti correttamente al grafico di dipendenza. Per assicurarti che vengano create dipendenze implicite, assicurati che le uscite facciano riferimento agli attributi delle risorse. Invece di fare riferimento direttamente a una variabile di input per un'istanza, passa l'attributo come mostrato di seguito:

    Consigliato:

    output "name" {
      description = "Name of instance"
      value       = google_compute_instance.main.name
    }
    

    Non consigliato:

    output "name" {
      description = "Name of instance"
      value       = var.name
    }
    

Utilizzare le origini dati

  • Posiziona le origini dati accanto alle risorse che fanno riferimento a queste. Ad esempio, se ottieni un'immagine da utilizzare per il lancio di un'istanza, posizionala accanto all'istanza anziché raccogliere le risorse di dati nel proprio file.
  • Se il numero di origini dati diventa elevato, ti consigliamo di spostarle in un file data.tf dedicato.
  • Per recuperare i dati relativi all'ambiente corrente, utilizza l'interpolazione delle variabili o delle risorse.

Limitare l'utilizzo di script personalizzati

  • Utilizza gli script solo quando necessario. Lo stato delle risorse create tramite gli script non viene preso in considerazione o gestito da Terraform.
    • Se possibile, evita gli script personalizzati. Utilizzale solo quando le risorse Terraform non supportano il comportamento desiderato.
    • Eventuali script personalizzati utilizzati devono avere un motivo chiaramente documentato per la loro esistenza e, idealmente, un piano di ritiro.
  • Terraform può chiamare script personalizzati tramite i provisioner, incluso il provisioner local-exec.
  • Inserisci gli script personalizzati chiamati da Terraform in una directory scripts/.

Includi gli script di supporto in una directory separata

  • Organizza gli script di supporto che non vengono chiamati da Terraform in una directory helpers/.
  • Documenta gli script di assistenza nel file README.md con spiegazioni e invocazioni di esempio.
  • Se gli script di supporto accettano argomenti, fornisci il controllo degli argomenti e --help l'output.

Inserire i file statici in una directory separata

  • I file statici a cui Terraform fa riferimento, ma che non esegue (ad esempio gli script di avvio caricati sulle istanze Compute Engine) devono essere organizzati in una directory files/.
  • Inserisci HereDocs di grandi dimensioni in file esterni, separati dal relativo HCL. Fai riferimento a queste variabili con la funzione file().
  • Per i file letti utilizzando la funzione templatefile di Terraform, usa l'estensione .tftpl.
    • I modelli devono essere posizionati in una directory templates/.

Proteggi le risorse stateful

Per le risorse stateful, come i database, assicurati che sia abilitata la protezione dall'eliminazione. Ad esempio:

resource "google_sql_database_instance" "main" {
  name = "primary-instance"
  settings {
    tier = "D0"
  }

  lifecycle {
    prevent_destroy = true
  }
}

Utilizzare la formattazione integrata

Tutti i file Terraform devono essere conformi agli standard di terraform fmt.

Limita la complessità delle espressioni

  • Limita la complessità di ogni singola espressione interpolata. Se in una singola espressione sono necessarie molte funzioni, valuta la possibilità di suddividerla in più espressioni utilizzando i valori locali.
  • Non avere mai più di un'operazione ternaria in una singola riga. Utilizza invece più valori locali per creare la logica.

Utilizzare count per i valori condizionali

Per creare un'istanza di una risorsa in modo condizionale, utilizza il meta-argomento count. Ad esempio:

variable "readers" {
  description = "..."
  type        = list
  default     = []
}

resource "resource_type" "reference_name" {
  // Do not create this resource if the list of readers is empty.
  count = length(var.readers) == 0 ? 0 : 1
  ...
}

Usa con parsimonia le variabili specificate dall'utente per impostare la variabile count per le risorse. Se per una variabile di questo tipo (ad es. project_id) viene fornito un attributo della risorsa e la risorsa non esiste ancora, Terraform non può generare un piano. Invece, Terraform segnala l'errore value of count cannot be computed. In questi casi, utilizza una variabile enable_x separata per calcolare la logica condizionale.

Utilizzare for_each per le risorse iterate

Se vuoi creare più copie di una risorsa in base a una risorsa di input, utilizza il meta-argomento for_each.

Pubblicare i moduli in un registry

Passaggi successivi