Only this pageAll pages
Powered by GitBook
1 of 15

Italiano (Italian)

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Concetti chiave

La documentazione ufficiale di Terraform descrive tutti gli aspetti di configurazione nei dettagli. Leggila attentamente per capire il resto della sezione.

Questa sezione descrive i concetti chiave che sono usati nel libro.

Risorsa (resource)

Una risorsa è aws_vpc, aws_db_instance, ecc. Una risorsa appartiene a un provider, accetta argomenti, fornisce output, attributi e ha un ciclo di vita. Una risorsa può essere creata, recuperata, aggiornata e cancellata.

Modulo Risorsa

Un modulo di risorsa è una collezione di risorse che insieme eseguono un'azione comune (per esempio AWS VPC Terraform module crea VPC, subnets, NAT gateway, ecc). Dipende dalla configurazione del provider, che può essere definito dentro il modulo oppure a un livello più alto della struttura (per esempio, in un modulo di infrastruttura).

Modulo di Infrastrutura

Un modulo di infrastruttura è una collezione di moduli risorsa, che possono non essere logicamente connessi, ma nella situazione/progetto/setup servono lo stesso scopo. Definisce la configurazione per i providers, che è passata ai moduli risorsa e alle risorse nei moduli sottostanti. Normalmente è limitata al lavoro di una entità per separatore logico (per esempio, AWS Region, Google Project).

Per esempio, il modulo terraform-aws-atlantis usa moduli risorse come terraform-aws-vpc e terraform-aws-security-group per amministrare l'infrastruttura richiesta per far girare Atlantis su AWS Fargate.

Un altro esempio è terraform-aws-cloudquery un modulo, dove moduli multipli di terraform-aws-modules sono usati insieme per amministrare l'infrastruttura, cosí come le risorse Docker usano i comandi build, push, e deploy per le immagini Docker.

Composizione

La Composizione è una collezione di moduli infrastruttura, che possono espandersi tra diverse aree separate (per esempio, AWS Regions, diversi accounts AWS ).

La Composizione è usata per descrivere un'infrastruttura completa richiesta per l'intera organizzazione o progetto.

Una composizione consiste di moduli infrastruttura, che consistono di moduli risorsa, che implementano risorse individuali.

Simple infrastructure composition

Data source

Data source esegue una operazione di sola lettura ed è dipendente dalla configurazione del provider, viene usato in un modulo risorsa e in un modulo infrastruttura.

Il Data source terraform_remote_state agisce come colla per moduli di alto livello e composizioni.

Il data source external permette a un programma di agire come un data source, esponendo dati arbitrari ad essere usati in qualche altra parte delle configurazione Terraform. Un esempio dal modulo terraform-aws-lambda dove il nome del file è calcolato chiamando un script python esterno.

Il data source http fa delle chiamate HTTP GET a un dato URL e esporta le informazioni sulle risposte, questo metodo è spesso usato per prendere le informazioni da endpoint dove un provider Terraform nativo non esiste.

Stato Remoto

Moduli di infrastruttura e composizioni dovrebbero persistere in uno stato remoto in una posizione remota dove possono essere recuperate da altri in maniera controllata (per esempio, specificando ACL, versionamento e con attivitá di log).

Provider, provisioner, ecc.

Providers, provisioners, e pochi altri termini sono ben descritti nella documentazione ufficiale e sarebbe inutile ripeterli qui. Secondo me hanno poco a che fare con lo scrivere dei buoni moduli Terraform.

Perchè è così difficile?

Mentre le risorse individuali sono come gli atomi nell'infrastruttura, i moduli di risorse sono come molecole. Un modulo è la più piccola unitá che si possa versionare e condividere. Ha una lista esatta di argomenti, implementa logiche di base per fare in modo che l'unitá esegua le funzionalitá richieste. Per esempio il modulo terraform-aws-security-group crea le risorse aws_security_group e aws_security_group_rule basandosi sul suo input. Questo modulo di risorse da solo puó essere usato insieme ad altri moduli per create moduli di infrastruttura.

L'accesso ai dati tra le molecole (moduli risorsa e moduli infrastruttura) viene eseguito usando output dei moduli e il data sources.

L'accesso ai dati tra le composizioni viene spesso effettuato usando il data source di tipo remote state. Ci sono molti modi di condividere dati tra le configurazioni.

Quando mettiamo in pratica i concetti descritti sopra una pseudo-relazione potrebbe apparire in questo modo:

composition-1 {
  infrastructure-module-1 {
    data-source-1 => d1

    resource-module-1 {
      data-source-2 => d2
      resource-1 (d1, d2)
      resource-2 (d2)
    }

    resource-module-2 {
      data-source-3 => d3
      resource-3 (d1, d3)
      resource-4 (d3)
    }
  }

}

Terraform

Terraform per infrastrutture di media dimensione

Sorgente: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/medium-terraform

Questo esempio contiene codice per strurtturare le configurazioni Terraform per infrastture di dimensioni medie che usano:

2 account AWS

  • 2 ambienti separati (prod e stage che non hanno niente in condivisione). Ogni ambiente vive in un account AWS separato

  • Ogni ambiente usa una versione differente del moduleo di infrastruttura dallo scaffale infrastructure module (alb) con sorgente Terraform Registry

  • Ogni ambiente usa la stessa versione del modulo interno modules/network dato che la sorgente di questo è una directory locale.

  • Perfetto per progetti dove l'infrastruttura é separata logicamente (account AWS separati)

  • Adatto dove non c'é necessità di modificare risorse condivise tra account AWS ( un ambiente = un account AWS = un file di stato)

  • Adatto dove non c'é necessità di orchestrare cambiamenti tra ambienti.

  • Adatto dove le risorse di infrastruttura sono intenzionalmente diverse per ambiente e non possono essere generalizzate. (esempio, alcune risorse sono assenti in un ambiente o in alcune regioni)

Con la crescita del progetto, diventerà difficile tenere questi ambienti aggiornati l'uno con l'altro. Va considerato l'uso di moduli di infrastruttura (dallo scaffale o interni) per task ripetibili.

Scrivere configurazioni Terraform

Usa locals per specificare dipendenze esplicite tra le risorse

È una maniera per aiutare Terraform, in modo che capisce che alcune risorse dovrebbero essere cancellate per prima anche se non c'è una dipendenza diretta nelle configurazioni Terraform.

https://raw.githubusercontent.com/antonbabenko/terraform-best-practices/master/snippets/locals.tf

Terraform 0.12 - Argomenti richiesti vs opzionali

  1. Argomenti richiesti index_document devono essere settati, se var.website non è una map vuota.

  2. Argomenti Opzionali error_document può essere omesso.

main.tf
variable "website" {
  type    = map(string)
  default = {}
}

resource "aws_s3_bucket" "this" {
  # omitted...

  dynamic "website" {
    for_each = length(keys(var.website)) == 0 ? [] : [var.website]

    content {
      index_document = website.value.index_document
      error_document = lookup(website.value, "error_document", null)
    }
  }
}
terraform.tfvars
website = {
  index_document = "index.html"
}

Terragrunt

Workshop

È disponibile un workshop per chi volesse fare pratica con quello descritto in questa guida.

Il contenuto è disponibile qui -

https://github.com/antonbabenko/terraform-best-practices-workshop

Esempi di strutturazione del codice

Struttura del codice Terraform

Questi esempi sono realizzati con il provider AWS ma la maggior parte dei principi mostrati possono essere applicati anche ad altri provider cloud e non (DNS, DB, Monitoring, ecc)

Tipo
Descrizione
Disponibilità

Poche risorse, nessuna dipendenza esterna. Un solo AWS account. Una sola Regione. Un solo ambiente.

Si

Più account AWS e ambienti, moduli standard di infrastruttura Terraform.

Si

Molti accounts AWS, molte regioni, importanza di ridurre il copia-incolla, moduli di infrastruttura personalizzati , pesante uso di composizioni. Uso di Terraform.

Non ancora disponibile

molto-grande

Più providers (AWS, GCP, Azure). Deploy Multi-cloud. Uso di Terraform.

No

Terragrunt code structures

Tipo
Descrizione
Disponibilità

medio

Diversi account AWS e ambienti, moduli di infrastruttura standard, pattern di composizione usando Terragrunt.

No

large

Molti accounts AWS, molte regioni, importanza di ridurre il copia-incolla, moduli di infrastruttura personalizzati , pesante uso di composizioni. Uso di Terragrunt.

No

very-large

Più providers (AWS, GCP, Azure). Deploy Multi-cloud. Uso di Terragrunt.

No

Struttura del codice

Le domande collegate alla strutturazione del codice Terraform sono le piú frequenti nella community. Tutti hanno pensato alla migliore maniera per strutturare il codice a un certo punto del progetto.

Come dovrei strutturare le mie configurazioni Terraform?

Questa è una delle domande dove sono presenti molte soluzioni, è molto difficile dare un consiglio universale, andiamo a capire meglio con cosa abbiamo a che fare.

  • Qual'è la complessitá del tuo progetto?

    • Numero di risorse collegate

    • Numero di provider Terraform (guarda la nota sotto sui "provider logici" )

  • Con che frequenza cambia la tua infrastruttura Terraform?

    • Da una volta a mese/settimana/giorno

    • A continuamente (ogni volta quando c'e' un nuovo commit)

  • Un cambiamento del codice può scatenare un aggiornamento? É permesso al CI server di aggiornare i repository quando viene fatto il build di un nuovo artefatto?

    • Solo gli sviluppatori possono fare il push al repository di infrastruttura

    • Tutti possono proporre un cambiamento a qualsiasi parte del progetto aprendo una PR ( includendo i task automatici che girano sul server CI)

  • Quale piattaforma o servizio usi per il deployment?

    • AWS CodeDeploy, Kubernetes, o OpenShift richiedono degli approcci leggermente differenti

  • Come sono raggruppati il ambienti?

    • Per ambiente, regione, progetto

I provider logici lavorano interamente con la logica Terraform e spesso non interagiscono con altri servizi, pensiamo alla loro complessità come O(1). I provider logici più comuni sono , , , , .

Cominciamo a strutturare le configurazioni Terraform.

Mettere tutto il codice dentro il file main.tf é una buona idea quando si sta cominciando o si sta scrivendo un codice di esempio. In tutti gli altri casi é meglio avere più file divisi logicamente in questo modo:

  • main.tf - chiamate ad altri moduli, locals, e data sources per creare altre risorse

  • variables.tf - contiene dichiarazioni di variabili usate dentro main.tf

  • outputs.tf - contiene outputs di risorse create dentro main.tf

  • versions.tf - contiene le versioni richieste per Terraform per per i providers

terraform.tfvars non dovrebbe essere mai usato eccetto nelle .

Come organizzare la struttura delle configurazioni Terraform?

Per favore assicurati di aver capito i concetti chiave - , , e , dato che verranno usati negli esempi seguenti.

Raccomandazioni per la struttura del codice.

  • È piu facile e veloce lavorare con un numero di risorse piccolo.

    • terraform plan e terraform apply eseguono delle chiamate API cloud per verificare lo stato delle risorse.

    • Se si ha l'intera infrastruttura in una composizione singola fare queste chiamate API puó richiedere molto tempo.

  • I danni a causati di un evento catastrofico sono minori con meno risorse.

    • Isolare risorse non collegate mettendole in composizioni separate riduce il rischio in caso qualcosa vada male.

  • Inizia il progetto usando lo stato remoto perchè :

    • Il laptop non è il posto per tenere la "fonte della verità" riguardo all'infrastruttura.

    • Amministrare il file tfstate in git é un incubo

    • Quando l'infrastruttura crescerà in direzioni multiple (aumentando il numero di risorse e dipendenze) sarà piú facile tenere tutto sotto controllo.

  • Fai pratica usando una struttura del codice consistente e una :

    • Come il codice procedurale, il codice Terraform dovrebbe essere scritto per essere letto dalle persone in prima istanza, la consistenza aiuterà quando ci sarà da fare cambiamenti dopo sei mesi.

    • È possibile spostare le risorse tra i file di stato di Terraform ma non sarà semplice se avrai una struttura di codice e un naming non consistente.

  • Tieni le risorse nei moduli nella maniera più pulita possibile.

  • Non fare hardcode di valori che possono essere passati come variabili o scoperti usando data sources

  • Usa data sources e terraform_remote_state come una colla tra moduli di infrastruttura con diverse composizioni.

In questo libro, gli esempi dei progetti sono raggruppati per complessità - dall'infrastruttura più piccola a quella più grande. Anche se la separazione non é restrittiva.

Orchestrazione di moduli infrastruttura e composizioni.

Avere un'infrastruttura piccola significa un numero di dipendenze minori e poche risorse. Quando il progetto cresce, anche la necessità di collegare l'esecuzione di configurazioni Terraform, connettere moduli di infrastruttura diversi, e passare valori con composizioni diventa ovvia.

Ci sono almeno 5 gruppi distinti di soluzioni di orchestrazione che uno sviluppatore usa:

  1. Solo Terraform. Approccio diretto, gli sviluppatori devono conoscere solo Terraform per compiere il lavoro.

  2. Terragrunt. Un tool di orchestrazione puro, che può essere usato per orchestrare l'intera infrastruttura e gestire le dipendenze. Terragrunt opera con moduli di infrastruttura e composizioni native, in questo modo riduce la duplicazione del codice.

  3. Scripts personalizzati. Spesso accade come punto di partenza verso l'orchestrazione e prima di scoprire Terragrunt.

  4. Ansible o tool simili di automazione. Solitamente quando Terraform viene adottato dopo Ansible, o quando è usata la UI di Ansible.

  5. e altre solutioni ispiriate a Kubernetes. Alcune volte ha senso utilizzare l'ecosistema Kubernets e impiegare un "reconciliation loop feature" per raggiungere lo stato desiderato della nostra configurazione Terraform. Guarda il video per avere più informazioni.

Tenendo presente tutto questo, il libro rivede i primi due approcci Terraform da solo oppure con Terragrunt.

Guarda gli esempi e la strutturazione del codice per o nel prossimo capitolo.

piccolo
media
grande
random
local
terraform
null
time
composizioni
modulo risorsa
modulo infrastruttura
composizione
convezione sui nomi
Crossplane
Crossplane vs Terraform
Terraform
Terragrunt

Referenze

Ci sono molte persone che creano grandi contenuti e amministrano progetti open-source rilevanti per la comunità Terraform. Non riesco a pensare alla maniera migliore per presentarli qui senza copiare quello elencato come awesome-terraform.

https://twitter.com/antonbabenko/lists/terraform-experts - Elenco di persone che lavorano con Terraform in maniera molto attiva e possono dire la loro (se domandi ovviamente).

https://github.com/shuaibiyy/awesome-terraform - Lista curata di risorse su HashiCorp's Terraform.

http://bit.ly/terraform-youtube - "La tua dose di Terraform settimanale" Il canale YouTube di Anton Babenko. Live streams con reviews, interviste, Q&A, live coding, e altri hack con Terraform.

https://weekly.tf - La newsletter settimanale di Terraform. Aggiornamenti nel mondo Terraform (progetti, annunci, discussioni) di Anton Babenko.

Benvenuti

Questo documento è un tentativo di descrivere le best practices nell'uso di Terraform e fornire suggerimenti per i problemi che accadono più frequentemente nell'uso di Terraform.

Terraform é un nuovo progetto (come la maggior parte degli strumenti di DevOps) inizato nel 2014.

Terraform é un potente (se non il piú potente disponibile al momento) e uno dei tool più usati, che permette l'approccio infrastruttura come codice. Abilita agli sviluppatori di fare molte cose, e non li limita a fare cose in un modo che è difficile da supportare o integrare con altri strumenti.

Alcune informazioni descritte in questo libro potrebbero non sembrare delle best practices. Voglio distinguere cosa sono delle best practices certe e stabilite e cosa invece sono opinioni. Alcune volte userò note per specificare meglio il contesto e icone per il livello di maturitá di ogni sottosezione.

Il libro é iniziato nel 2018 in una soleggiata Madrid ed é disponibile gratuitamente qui - https://www.terraform-best-practices.com/ .

Qualche anno dopo é sto aggiornato con alcune delle piú recenti best practices in Terraform 1.0. Infine, questo libro dovrebbe contenere alcune delle più indiscutibili best practices e raccomandazioni per utenti di Terraform.

Nota del traduttore: sono stato molto combattuto (e ho chiesto consiglio ad altre persone che come me lavorano nell'informatica) se tradurre best practices oppure no. Alla fine ho deciso che le "pratiche migliori" , o "stato dell'arte", "pratiche buone" non rendeva bene il termine e quindi l'ho lasciato in inglese.

Sponsors

Please contact me if you want to become a sponsor.

— Terraform Compliance Simplified. Make your Terraform modules compliance-ready.

—

Traduzioni

Contattami se vuoi tradurre il libro in altre lingue.

Contributi

Sono sempre alla ricerca di feedback e desidero aggiornare questo libro con il maturare della comunity. Nuove idee e implementazioni verranno valutate e verificate.

Se sei interessato in alcuni argomenti per favore fai una richiesta (open an issue), oppure mettipi un mi piace su una giá aperta a cui sei interessato. Se credi di porter fornire contenuti e vuoi contribuire, scrivi una bozza e manda una pull request (non preoccuparti di scrivere del buon contenuto in questa fase!)

Autori

Questo libro é mantenuto da Anton Babenko con l'aiuto di diversi traduttori e collaboratori.

Licenza

Questo contenuto é sotto la licenza Apache 2. Controlla LICENSE per maggiori dettagli.

Gli autori e i collaboratori di questo contenuto non possono garantire la validitá delle informazioni. Per favore assicurati di capire che le informazioni fornite qui sono date in maniera gratuita, non c'é nessuno accordo o contratto tra te e ogni persona associata al contenuto e al progetto. Gli autori e i collaboratori non si assumano e con la presente declinano qualsivoglia responsabilitá a ogni parte per qualsiasi perdita, danneggiamento o discontinuitá causata da errori o omissioni nelle informazioni contenute, associate o collegate a questo contenuto, sia che siano errori o omissioni causate da negligenza, o qualsiasi altra causa.

Copyright © 2018-2023 Anton Babenko.

Compliance.tf
العربية (Arabic)
Bosanski (Bosnian)
Português (Brazilian Portuguese)
English
Français (French)
ქართული (Georgian)
Deutsch (German)
ελληνικά (Greek)
עברית (Hebrew)
हिंदी (Hindi)
Bahasa Indonesia (Indonesian)
日本語 (Japanese)
ಕನ್ನಡ (Kannada)
한국어 (Korean)
Polski (Polish)
Română (Romanian)
简体中文 (Simplified Chinese)
Español (Spanish)
Türkçe (Turkish)
Українська (Ukrainian)
اردو (Urdu)

FAQ

FTP (Frequent Terraform Problems)

Quali sono gli strumenti che dovrei conoscere e considerare l'utilizzo?

  • Terragrunt - strumento di orchestrazione

  • tflint - Code linter

  • tfenv - Version manager

  • Atlantis - Automatizzazione delle pull request

  • pre-commit-terraform - Collezione di git hooks per Terraform da usare con pre-commit framework

Quali sono le soluzioni al dependency hell con i moduli?

Le versioni delle risorse e dei moduli infrastruttura dovrebbero essere specificati. I providers dovrebbero essere configurati fuori dai moduli, ma solo in composizione. È possibile fare il lock sulle versioni dei providers.

Non c'è una dipendenza master per il tool di management, ma ci sono alcuni suggerimenti per rendere il dependency hell meno problematico. Per esempio, Dependabot può essere usato per automatizzare gli aggiornamenti delle dipendenze. Dependabot crea delle pull requests per mantenere le dipendenze sicure e aggiornate. Dependabot supporta le configurazioni Terraform.

Convenzioni sui nomi

Convenzioni generali

Non ci dovrebbero essere ragioni per non seguire queste convenzioni :)

Presta attenzione che le risorse cloud hanno spesso restrizioni sui nomi consentiti. Alcune risorse, per esempio, non possono contenere il trattino "-", alcune devono essere camel-cased. Le convenzioni nel libro si riferiscono ai nomi Terraform.

  1. Usa _ (trattino basso) invece del - (trattino) ovunque (nomi sul tipo resourse, nomi sul tipo data, nomi di variabili, outputs, ecc).

  2. Preferisci l'uso di lettere minuscole e numero (perfino dove é supportato UTF-8).

Argomenti di resource and data source

  1. Non ripetere il tipo di risorsa nel nome della risorsa (ne parzialmente ne interamente):

    resource "aws_route_table" "public" {}

    resource "aws_route_table" "public_route_table" {}

    resource "aws_route_table" "public_aws_route_table" {}

  2. Il nome delle risorse dovrebbe essere chiamatothis se non c'è disponibile un nome più descrittivo e generale, o se il modulo di risorsa crea una singola risorsa di questo tipo (per esempio, in AWS VPC module c'è una singola risorsa di tipo aws_nat_gateway e risorse multiple di tipo aws_route_table, quindi aws_nat_gateway dovrebbe essere chiamato this e aws_route_table dovrebbe avere un nomi più descrittivi come per esempio private, public, database).

  3. Usare sempre nomi al singolare.

  4. Usa- (il trattino )dentro i valori degli argomenti interni e in posti dove i valori sono esposti agli essere umani (per esempio, dentro i nomi DNS o le istanze RDS).

  5. Includi l'argomento count / for_each dentro la risorsa o il blocco di data source come primo argomento in cima separalo da una nuova linea dopo di lui.

  6. Includi argomenti di tipo tags, se supportati dalla risorsa, come ultimo argomento, seguito dal depends_on e lifecycle, se necessario. Tutti questi dovrebbero essere separati da una singola linea vuota.

  7. Quando si usano le condizioni in un argomento count / for_each preferisci valori boleani invece di usare length o un'altra espressione.

Esempi di codice di resource

Uso di count / for_each

main.tf
resource "aws_route_table" "public" {
  count = 2

  vpc_id = "vpc-12345678"
  # ... remaining arguments omitted
}

resource "aws_route_table" "private" {
  for_each = toset(["one", "two"])

  vpc_id = "vpc-12345678"
  # ... remaining arguments omitted
}
main.tf
resource "aws_route_table" "public" {
  vpc_id = "vpc-12345678"
  count  = 2

  # ... remaining arguments omitted
}

Posizionamento di tags

main.tf
resource "aws_nat_gateway" "this" {
  count = 2

  allocation_id = "..."
  subnet_id     = "..."

  tags = {
    Name = "..."
  }

  depends_on = [aws_internet_gateway.this]

  lifecycle {
    create_before_destroy = true
  }
}   
main.tf
resource "aws_nat_gateway" "this" {
  count = 2

  tags = "..."

  depends_on = [aws_internet_gateway.this]

  lifecycle {
    create_before_destroy = true
  }

  allocation_id = "..."
  subnet_id     = "..."
}

Condizioni in count

outputs.tf
resource "aws_nat_gateway" "that" {    # Best
  count = var.create_public_subnets ? 1 : 0
}

resource "aws_nat_gateway" "this" {    # Good
  count = length(var.public_subnets) > 0 ? 1 : 0
}

Variabili

  1. Non reinventare la ruota in moduli risorsa: usa name, description, e il valore didefault per le variabili come sono definitie nella sezione "Argument Reference" per le risorse con cui stai lavorando.

  2. Il supporto per la validazione nelle variabili è piuttosto limitato (per esempio non è possibile accedere a altre variabili o fare lookups). Bisogna tenerne conto perchè in molti casi questa feature è inutile.

  3. Usare la forma plurale nel nome delle variabili quando il tipo è list(...) o map(...).

  4. Ordina le chiavi in un blocco per le variabil in questo modo: description , type, default, validation.

  5. Includere sempre la descrizione description su tutte le variabili perfino se pensi che è ovvio (potresti averne bisogno in futuro).

  6. Usa se è possibile tipi semplici (number, string, list(...), map(...), any) invece di tipi specifici come object() a meno che hai bisogno di fare costrizioni specifiche su ogni chiave.

  7. Usa tipi specifici come map(map(string)) se tutti gli elementi della mappa hanno lo stesso tipo (per esempio string) o possono essere convertiti (per esempio il tipo number può essere convertito in una string).

  8. Usa il tipo any, la validazione sul tipo iniziando da una certa profondità o quando tipo multipli dovrebbero essere supportati.

  9. Value {} alcune volte è una map ma altre volte un object. Usa tomap(...) per creare una map in questo modo sei sicuro di non fare un oggetto.

Outputs

Fai in modo che gli outputs siano consistenti e comprensibilit fuori dal loro raggio d'azione (quando un utente sta usando un modulo dovrebbe essere ovvio cosa un tipo o il valore di un attributo restituiscono).

  1. Il nome di un output dovrebbe descrivere la proprietà che contiene ed essere meno libero della forma che normalmente vorresti.

  2. Una buona struttura per il nome di un output apparirà in questa maniera {name}_{type}_{attribute} , dove:

    1. {name} è una risorsa o un data source senza il prefisso del provider. {name} per aws_subnet è subnet, peraws_vpc èvpc.

    2. {type} è un tipo di una risorsa sorgente

    3. {attribute} è un attributo restituito da un output

    4. Vedi gli esempi.

  3. Se l'output sta restituendo un valore con funzioni di interpolazione e risorse multiple, {name} e {type} dovrebbero essere quanto più generici possibile (this è un prefisso e dovrebbe essere omesso). Vedi gli esempi.

  4. Se il valore restituito è una lista dovrebbe avere un nome plurale. Vedi gli esempi.

  5. Includere sempre la descrizionedescription per tutti gli output anche se pensi che sia ovvio.

  6. Evita di settare argomenti sensitive a meno che hai il controllo totale su tutti gli output in tutti i punti dei moduli.

  7. Preferisci l'uso di try() (disponibile da Terraform 0.13) invece di element(concat(...)) (approccio legacy per le versioni prima della 0.13)

Esempi di codice di output

Restituire al massimo un security group ID:

outputs.tf
output "security_group_id" {
  description = "The ID of the security group"
  value       = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
}

Quando abbiamo risorse multiple dello stesso tipo, this dovrebbe essere omesso nel nome dell'output:

outputs.tf
output "this_security_group_id" {
  description = "The ID of the security group"
  value       = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
}

Usare un nome pluralre se il valore restituito e' una lista

outputs.tf
output "rds_cluster_instance_endpoints" {
  description = "A list of all cluster instance endpoints"
  value       = aws_rds_cluster_instance.this.*.endpoint
}

Terraform per infrastrutture di grandi dimensioni

Sorgente: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/large-terraform

Questo esempio contiene codice per strutturare configurazioni Terraform per infrastrutture di grandi dimensioni che usano:

  • 2 account AWS

  • 2 regioni

  • 2 ambienti separati (prod e stage che non hanno niente in condivisione). Ogni ambiente vive in un account AWS separato e si distribuisce tra 2 regioni

  • Ogni ambiente usa una versione differente del moduleo di infrastruttura off-the-shelf infrastructure module (alb) con sorgenteTerraform Registry

  • Ogni ambiente usa la stessa versione del modulo interno modules/network dato che la sorgente di questo è una directory locale.

In un progetto grande come quello descritto i benefici di usare Terragrunt diventano molto evidenti. Vedi Code Structures examples with Terragrunt.

  • Perfetto per progetti dove l'infrastruttura é separata logicamente (account AWS separati)

  • Adatto dove non c'é necessità di modificare risorse condivise tra account AWS ( un ambiente = un account AWS = un file di stato)

  • Adatto dove non c'é necessità di orchestrare cambiamenti tra ambienti.

  • Adatto dove le risorse di infrastruttura sono intenzionalmente diverse per ambiente e non possono essere generalizzate. (esempio, alcune risorse sono assenti in un ambiente o in alcune regioni)

Quando il progetto crescerà, sarà più difficile tenere questi ambienti aggiornati uno con l'altro. Considera l'uso dei moduli infrastruttura (dallo scaffale o interni) per attività che si ripetono.

Terraform per infrastrutture di piccole dimensioni

Sorgente: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/small-terraform

Questo esempio contiene codice per la strutturazione delle configurazioni Terraform per un infrastruttura di piccole dimensioni, dove non sono usate dipendenze esterne.

  • Perfetto per iniziare e fare la rifattorizzazione mentre procedi.

  • Perfetto per moduli con poche risorse

  • Buono per moduli di infrastrutture piccoli e lineari come (per esempio, terraform-aws-atlantis)

  • Buono per un piccolo numero di risorse (meno di 20-30)

Un singolo file di stato per tutte le risorse, può rendere il processo di esecuzione di Terraform lento se il numero di risorse é in crescita (considera l'uso dell'argomento -target per limitare il numero di risorse)

Stili di codice

  • Esempi di moduli Terraform dovrebbero contenere la documentazione che spiega le features e come usarle.

  • Tutti i links nel README.md dovrebbero essere con path assoluti per fare in modo che il sito web Terraform Registry li mostri correttamente.

  • La documentation può includere diagrammi creati con mermaid e blueprints creati con cloudcraft.co.

  • Usa i Terraform pre-commit hooks per essere sicuri che il codice è valido, correttamente formattato e automaticamente documentation prima che venga pushato in git e controllato da altri sviluppatori.

Documentazione

Generare automaticamente la documentazione

pre-commit è un framework per amministrare e mantenere hooks per linguaggi multipli. È scritto in Python ed è un tool potente per fare qualcosa automaticamente sulla macchina dello sviluppatore prima che il codice venga committato sul repository git. Normalmente, è usato per far girare linters e formattare il codice (vedi supported hooks).

Con le configurazioni Terraform pre-commit può essere usato per formattare e validare il codice, come per aggiornare la documentatione.

Dai un'occhiato al repository pre-commit-terraform per prendere confidenza e anche ai repositories (eg, terraform-aws-vpc) dov'è già usato.

terraform-docs

terraform-docs è un tool che genera la documentaione dei moduli Terraform in vari formati di output. Puoi farlo girare manualmente (senza pre-commit hooks), oppure usare pre-commit-terraform hooks per fare in modo che la documentazione si aggiorni automaticamente.

@todo: Document module versions, release, GH actions

Risorse

  1. pre-commit framework homepage

  2. Collection of git hooks for Terraform to be used with pre-commit framework

  3. Blog post by Dean Wilson: pre-commit hooks and terraform - a safety net for your repositories