Infrastruttura Terraform
Terraform è uno strumento software open-source di infrastructure as code che consente di creare, modificare e migliorare l’infrastruttura in modo sicuro e prevedibile.
Il generatore di infrastruttura Terraform crea un progetto di infrastruttura Terraform. L’applicazione generata include le best practice di sicurezza attraverso i controlli di sicurezza di Checkov.
Utilizzo
Sezione intitolata “Utilizzo”Generare un progetto Terraform
Sezione intitolata “Generare un progetto Terraform”Puoi generare un nuovo progetto Terraform in due modi:
Esegui questo generatore@aws/nx-plugin:terraform#project
pnpm nx g @aws/nx-plugin:terraform#project yarn nx g @aws/nx-plugin:terraform#project npx nx g @aws/nx-plugin:terraform#project bunx nx g @aws/nx-plugin:terraform#project- Installa il Nx Console VSCode Plugin se non l'hai già fatto
- Apri la console Nx in VSCode
- Clicca su
Generate (UI)nella sezione "Common Nx Commands" - Cerca
@aws/nx-plugin - terraform#project - Compila i parametri richiesti
- Clicca su
Generate
Componi il tuo comando5
Obbligatorio
Opzioni
Sezione intitolata “Opzioni”nameObbligatoriostringIl nome del progetto.
typeenumPredefinito:applicationSe si tratta di una libreria terraform (moduli riutilizzabili) o di un'app (distribuibile).
applicationlibrarydirectorystringPredefinito:packagesLa directory del nuovo progetto.
subDirectorystringLa sottodirectory in cui viene posizionato il progetto. Per impostazione predefinita corrisponde al nome del progetto.
preferInstallDependenciesbooleanPredefinito:trueSe preferire l'installazione delle dipendenze dopo l'esecuzione del generatore. Impostare su false per rimandare l'installazione quando si eseguono più generatori in batch (l'installazione viene comunque eseguita se necessaria affinché i generatori successivi possano calcolare il grafo dei progetti Nx); installare una volta alla fine.
Output del generatore
Sezione intitolata “Output del generatore”Il generatore crea diverse strutture di file a seconda del tipo di progetto:
Tipo Application
Sezione intitolata “Tipo Application”Per i progetti application (--type=application), il generatore crea un’applicazione Terraform completa con gestione dello stato remoto:
Directorysrc
- main.tf File di configurazione Terraform principale
- providers.tf Configurazione del provider con backend S3
- variables.tf Definizioni delle variabili di input
- outputs.tf Definizioni dei valori di output
Directoryenv File di variabili specifici per ambiente
- dev.tfvars Variabili dell’ambiente di sviluppo
Directorybootstrap Configurazione di bootstrap per lo stato remoto
- main.tf Bucket S3 e policy per l’archiviazione dello stato
- providers.tf Configurazione del provider AWS
- variables.tf Definizioni delle variabili di bootstrap
Directoryscripts Helper Node eseguiti dai target nx
bootstrap,bootstrap-destroyeinit- aws-config.ts Risolve account + regione tramite la catena di credenziali AWS SDK
- bootstrap.ts Esegue pull/push del tfstate di bootstrap ed esegue
terraform apply - bootstrap-destroy.ts Svuota il bucket di stato ed esegue
terraform destroy - init.ts Esegue
terraform initcon la configurazione del backend S3 - env.ts Punta
terraform initalla cache condivisa dei provider
- checkov.yml Configurazione di Checkov, inclusi i controlli da saltare
- project.json Configurazione del progetto e target di build
Tipo Library
Sezione intitolata “Tipo Library”Per i progetti library (--type=library), il generatore crea una struttura più semplice per moduli Terraform riutilizzabili:
Directorysrc
- main.tf File del modulo Terraform principale
- checkov.yml Configurazione di Checkov, inclusi i controlli da saltare
- project.json Configurazione del progetto e target di build
Implementare la tua infrastruttura Terraform
Sezione intitolata “Implementare la tua infrastruttura Terraform”Puoi iniziare a scrivere la tua infrastruttura Terraform all’interno di src/main.tf, per esempio:
locals { account_id = data.aws_caller_identity.current.account_id aws_region = data.aws_region.current.id}
resource "null_resource" "print_info" { # triggers = { # always_run = timestamp() # }
provisioner "local-exec" { command = "echo 'AWS Region: ${local.aws_region}, AWS Account: ${local.account_id}, Environment: ${var.environment}'" }}
# Declare your infrastructure hereresource "aws_s3_bucket" "my_bucket" { bucket = "my-unique-bucket-name"}Nota che il bucket S3 sopra fallirebbe la scansione di sicurezza Checkov, che verifica che il bucket abbia le impostazioni di sicurezza appropriate abilitate.
Dipendenze tra progetti
Sezione intitolata “Dipendenze tra progetti”Se volessi eseguire un modulo da un progetto separato (lib), potresti farlo come segue:
module "lib_module" { source = "../../path/to/my-lib/src"}Questo aggiornerà automaticamente il grafo Nx per aggiungere una dipendenza tra la tua applicazione consumatrice e la tua lib.
Configurazione dell’ambiente
Sezione intitolata “Configurazione dell’ambiente”Configura le variabili specifiche per ambiente nei file src/env/*.tfvars.
Per aggiungere nuovi ambienti, crea un nuovo file src/env/<environment>.tfvars con le variabili specifiche per l’ambiente e aggiungi nuove voci per apply, destroy, init, plan nel project.json per la nuova configurazione dell’ambiente. Per esempio, supponiamo di voler aggiungere un ambiente prod:
# Production environment variablesenvironment = "prod"aws_region = "us-west-2"{ "targets": { "apply": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform apply ../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform apply ../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["plan"] }, "destroy": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform destroy -var-file=env/dev.tfvars" }, "prod": { "command": "terraform destroy -var-file=env/prod.tfvars" } }, "options": { "forwardAllArgs": true, "cwd":"{projectRoot}/src" }, "dependsOn": ["init"] }, "init": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "env": { "TF_ENV": "dev" } }, "prod": { "env": { "TF_ENV": "prod" } } }, "options": { "forwardAllArgs": true, "commands": ["tsx {projectRoot}/scripts/init.ts {projectRoot}"], "cwd": "{workspaceRoot}" } }, "plan": { "executor": "nx:run-commands", "defaultConfiguration": "dev", "configurations": { "dev": { "command": "terraform plan -var-file=env/dev.tfvars -out=../../../dist/packages/infra/terraform/dev.tfplan" }, "prod": { "command": "terraform plan -var-file=env/prod.tfvars -out=../../../dist/packages/infra/terraform/prod.tfplan" } }, "options": { "forwardAllArgs": true, "cwd": "{projectRoot}/src" }, "dependsOn": ["init"] } }}Bootstrap dello stato remoto (solo progetti Application)
Sezione intitolata “Bootstrap dello stato remoto (solo progetti Application)”Prima di distribuire la tua infrastruttura, dovrai eseguire il bootstrap del backend dello stato remoto. Questo crea un bucket S3 per archiviare i tuoi file di stato Terraform:
pnpm nx bootstrap tf-infrayarn nx bootstrap tf-infranpx nx bootstrap tf-infrabunx nx bootstrap tf-infraTarget disponibili
Sezione intitolata “Target disponibili”I target disponibili dipendono dal tipo di progetto:
Target comuni (sia Application che Library)
Sezione intitolata “Target comuni (sia Application che Library)”Validare la tua infrastruttura
Sezione intitolata “Validare la tua infrastruttura”Puoi validare la tua configurazione Terraform utilizzando il target validate:
pnpm nx validate tf-infrayarn nx validate tf-infranpx nx validate tf-infrabunx nx validate tf-infraLinting
Sezione intitolata “Linting”I progetti Terraform utilizzano terraform fmt per verificare la formattazione.
Eseguire il Linter
Sezione intitolata “Eseguire il Linter”Per invocare il linter per controllare il tuo progetto, puoi eseguire il target lint.
pnpm nx lint tf-infrayarn nx lint tf-infranpx nx lint tf-infrabunx nx lint tf-infraCorreggere i problemi di Lint
Sezione intitolata “Correggere i problemi di Lint”La maggior parte dei problemi di linting o formattazione può essere corretta automaticamente eseguendo con l’argomento --configuration=fix.
pnpm nx lint tf-infra --configuration=fixyarn nx lint tf-infra --configuration=fixnpx nx lint tf-infra --configuration=fixbunx nx lint tf-infra --configuration=fixAllo stesso modo, se desideri correggere tutti i problemi di lint in tutti i pacchetti nel tuo workspace, puoi eseguire:
pnpm nx run-many --target lint --all --configuration=fixyarn nx run-many --target lint --all --configuration=fixnpx nx run-many --target lint --all --configuration=fixbunx nx run-many --target lint --all --configuration=fixSaltare i problemi di Lint
Sezione intitolata “Saltare i problemi di Lint”Per evitare che i problemi di linting ti rallentino durante lo sviluppo (in particolare se hai problemi non correggibili automaticamente nel tuo progetto), puoi eseguire una build con la configurazione skip-lint:
pnpm nx run-many --target build --configuration=skip-lintyarn nx run-many --target build --configuration=skip-lintnpx nx run-many --target build --configuration=skip-lintbunx nx run-many --target build --configuration=skip-lintQuesto salta completamente il controllo di formattazione durante la build.
Test di sicurezza
Sezione intitolata “Test di sicurezza”Esegui controlli di sicurezza sulla tua infrastruttura utilizzando Checkov con il target checkov:
pnpm nx checkov tf-infrayarn nx checkov tf-infranpx nx checkov tf-infrabunx nx checkov tf-infraTroverai i risultati dei test di sicurezza nella cartella dist principale, sotto dist/packages/<my-terraform-project>/checkov.
Checkov viene eseguito come parte di build.
I controlli sono configurati nel file checkov.yml del progetto. Aggiungi un id di controllo a skip-check per sopprimerlo nell’intero progetto:
skip-check: - CKV_AWS_115 # Concurrent execution limit - CKV_AWS_116 # Dead Letter QueuePer sopprimere un controllo per una singola risorsa invece, aggiungi un commento #checkov:skip=<id>:<reason> all’interno del blocco della risorsa:
resource "aws_s3_bucket" "example" { #checkov:skip=CKV_AWS_18:Access logging not required for this bucket bucket = "example"}Eseguire i test Terraform
Sezione intitolata “Eseguire i test Terraform”Il target test esegue il framework di test nativo di Terraform su qualsiasi file .tftest.hcl nel tuo progetto:
pnpm nx test tf-infrayarn nx test tf-infranpx nx test tf-infrabunx nx test tf-infraUn progetto senza file di test è un successo senza operazioni, quindi puoi aggiungere test quando ne hai bisogno. build esegue questo target, quindi i tuoi test vengono eseguiti come parte di una build normale.
Ogni blocco run valuta la tua configurazione. Usa command = plan per verificare cosa farebbe Terraform (questo espande l’intero grafo dei moduli, quindi cattura errori in fase di pianificazione che validate non può rilevare), oppure command = apply per creare risorse reali e fare asserzioni sui loro output. Dichiarare mock_provider significa che non vengono effettuate chiamate API e non sono necessarie credenziali AWS, il che mantiene i test plan veloci e sicuri da eseguire in CI:
mock_provider "aws" { mock_data "aws_caller_identity" { defaults = { account_id = "123456789012" } } mock_data "aws_region" { defaults = { region = "us-east-1" } }}
variables { aws_region = "us-east-1" environment = "dev"}
run "plan_is_valid" { command = plan
assert { condition = data.aws_caller_identity.current.account_id == "123456789012" error_message = "Unexpected account id" }}Imposta ogni variabile richiesta dalla tua configurazione nel blocco variables, altrimenti l’esecuzione fallisce con “has a required variable … with no set value”.
Ogni target che esegue terraform init riutilizza una cache dei provider in .terraform/plugin-cache nella radice del tuo workspace, quindi i provider vengono scaricati una sola volta anziché ad ogni esecuzione. Ogni progetto ottiene la propria directory lì: due esecuzioni di terraform init che riempiono una cache contemporaneamente possono ciascuna calcolare un hash diverso per lo stesso provider, che terraform poi rifiuta confrontandolo con il tuo .terraform.lock.hcl. Consulta la documentazione Terraform per ulteriori informazioni.
Imposta TF_PLUGIN_CACHE_DIR nel tuo ambiente per puntare lo script init fornito a una cache che gestisci tu stesso — ad esempio un volume condiviso tra workspace. Nota che il target test legge il suo percorso da project.json, quindi modificalo anche lì.
Target solo per Application
Sezione intitolata “Target solo per Application”I seguenti target sono disponibili solo per i progetti di tipo application:
Pianificare la tua infrastruttura
Sezione intitolata “Pianificare la tua infrastruttura”Prima di applicare le modifiche, puoi vedere cosa farà Terraform eseguendo il target plan:
pnpm nx plan tf-infrayarn nx plan tf-infranpx nx plan tf-infrabunx nx plan tf-infraQuesto creerà un file di piano in dist/packages/<my-terraform-project>/terraform/dev.tfplan.
plan dipende da assemble, quindi produce gli artefatti a cui fanno riferimento i tuoi moduli, come i bundle Lambda e i metadati delle operazioni generate, senza eseguire i gate di lint, test e type-check.
Inizializzare Terraform
Sezione intitolata “Inizializzare Terraform”Inizializza la tua directory di lavoro Terraform con il target init:
pnpm nx run tf-infra:inityarn nx run tf-infra:initnpx nx run tf-infra:initbunx nx run tf-infra:initDistribuire su AWS
Sezione intitolata “Distribuire su AWS”Dopo la pianificazione, puoi distribuire la tua infrastruttura su AWS utilizzando il target apply:
pnpm nx apply tf-infrayarn nx apply tf-infranpx nx apply tf-infrabunx nx apply tf-infraOttenere gli output
Sezione intitolata “Ottenere gli output”Recupera i valori di output dalla tua configurazione Terraform:
pnpm nx output tf-infrayarn nx output tf-infranpx nx output tf-infrabunx nx output tf-infraDistruggere l’infrastruttura
Sezione intitolata “Distruggere l’infrastruttura”Quando devi smantellare la tua infrastruttura, usa il target destroy:
pnpm nx destroy tf-infrayarn nx destroy tf-infranpx nx destroy tf-infrabunx nx destroy tf-infraDistruggere le risorse di bootstrap
Sezione intitolata “Distruggere le risorse di bootstrap”Per pulire le risorse di bootstrap (bucket S3 per l’archiviazione dello stato):
pnpm nx bootstrap-destroy tf-infrayarn nx bootstrap-destroy tf-infranpx nx bootstrap-destroy tf-infrabunx nx bootstrap-destroy tf-infraQuesto svuota il bucket di stato prima di distruggerlo e risolve la regione dalla catena di credenziali AWS SDK, quindi viene eseguito in modo automatico in CI.
Ulteriori informazioni
Sezione intitolata “Ulteriori informazioni”Per ulteriori informazioni su Terraform, consulta la Documentazione Terraform e la Documentazione del provider AWS.