Salta ai contenuti

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.

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
Componi il tuo comando5

Obbligatorio

Opzioni del generatore5 opzioni
nameObbligatoriostring

Il nome del progetto.

typeenumPredefinito: application

Se si tratta di una libreria terraform (moduli riutilizzabili) o di un'app (distribuibile).

applicationlibrary
directorystringPredefinito: packages

La directory del nuovo progetto.

subDirectorystring

La sottodirectory in cui viene posizionato il progetto. Per impostazione predefinita corrisponde al nome del progetto.

preferInstallDependenciesbooleanPredefinito: true

Se 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.

Il generatore crea diverse strutture di file a seconda del tipo di progetto:

type = 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-destroy e init
    • 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 init con la configurazione del backend S3
    • env.ts Punta terraform init alla cache condivisa dei provider
  • checkov.yml Configurazione di Checkov, inclusi i controlli da saltare
  • project.json Configurazione del progetto e target di build
type = 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

Puoi iniziare a scrivere la tua infrastruttura Terraform all’interno di src/main.tf, per esempio:

src/main.tf
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 here
resource "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.

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.

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 variables
environment = "prod"
aws_region = "us-west-2"
type = application

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:

Terminal window
pnpm nx bootstrap tf-infra

I target disponibili dipendono dal tipo di progetto:

Puoi validare la tua configurazione Terraform utilizzando il target validate:

Terminal window
pnpm nx validate tf-infra

I progetti Terraform utilizzano terraform fmt per verificare la formattazione.

Per invocare il linter per controllare il tuo progetto, puoi eseguire il target lint.

Terminal window
pnpm nx lint tf-infra

La maggior parte dei problemi di linting o formattazione può essere corretta automaticamente eseguendo con l’argomento --configuration=fix.

Terminal window
pnpm nx lint tf-infra --configuration=fix

Allo stesso modo, se desideri correggere tutti i problemi di lint in tutti i pacchetti nel tuo workspace, puoi eseguire:

Terminal window
pnpm nx run-many --target lint --all --configuration=fix

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:

Terminal window
pnpm nx run-many --target build --configuration=skip-lint

Questo salta completamente il controllo di formattazione durante la build.

Esegui controlli di sicurezza sulla tua infrastruttura utilizzando Checkov con il target checkov:

Terminal window
pnpm nx checkov tf-infra

Troverai 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:

checkov.yml
skip-check:
- CKV_AWS_115 # Concurrent execution limit
- CKV_AWS_116 # Dead Letter Queue

Per 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"
}

Il target test esegue il framework di test nativo di Terraform su qualsiasi file .tftest.hcl nel tuo progetto:

Terminal window
pnpm nx test tf-infra

Un 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:

src/main.tftest.hcl
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ì.

type = application

I seguenti target sono disponibili solo per i progetti di tipo application:

Prima di applicare le modifiche, puoi vedere cosa farà Terraform eseguendo il target plan:

Terminal window
pnpm nx plan tf-infra

Questo 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.

Inizializza la tua directory di lavoro Terraform con il target init:

Terminal window
pnpm nx run tf-infra:init

Dopo la pianificazione, puoi distribuire la tua infrastruttura su AWS utilizzando il target apply:

Terminal window
pnpm nx apply tf-infra

Recupera i valori di output dalla tua configurazione Terraform:

Terminal window
pnpm nx output tf-infra

Quando devi smantellare la tua infrastruttura, usa il target destroy:

Terminal window
pnpm nx destroy tf-infra

Per pulire le risorse di bootstrap (bucket S3 per l’archiviazione dello stato):

Terminal window
pnpm nx bootstrap-destroy tf-infra

Questo 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.

Per ulteriori informazioni su Terraform, consulta la Documentazione Terraform e la Documentazione del provider AWS.