Ir al contenido

Infraestructura Terraform

Terraform es una herramienta de software de infraestructura como código de código abierto que te permite crear, cambiar y mejorar infraestructura de manera segura y predecible.

El generador de infraestructura Terraform crea un proyecto de infraestructura Terraform. La aplicación generada incluye mejores prácticas de seguridad a través de verificaciones de seguridad de Checkov.

Puedes generar un nuevo proyecto Terraform de dos maneras:

Ejecute este generador@aws/nx-plugin:terraform#project

pnpm nx g @aws/nx-plugin:terraform#project
Construya su comando5

Requerido

Opciones del generador5 opciones
nameRequeridostring

El nombre del proyecto.

typeenumPredeterminado: application

Si esto es una lib de terraform (módulos reutilizables) o app (desplegable).

applicationlibrary
directorystringPredeterminado: packages

El directorio del nuevo proyecto.

subDirectorystring

El subdirectorio en el que se coloca el proyecto. Por defecto, este es el nombre del proyecto.

preferInstallDependenciesbooleanPredeterminado: true

Si se prefiere instalar las dependencias después de que se ejecute el generador. Establecer en false para diferir la instalación cuando se ejecutan múltiples generadores en lote (la instalación aún se ejecuta si es necesario para que los generadores subsiguientes puedan calcular el grafo de proyectos de Nx); instalar una vez al final.

El generador crea diferentes estructuras de archivos dependiendo del tipo de proyecto:

type = application

Para proyectos de aplicación (--type=application), el generador crea una aplicación Terraform completa con gestión de estado remoto:

  • Directoriosrc
    • main.tf Main Terraform configuration file
    • providers.tf Provider configuration with S3 backend
    • variables.tf Input variable definitions
    • outputs.tf Output value definitions
    • Directorioenv Environment-specific variable files
      • dev.tfvars Development environment variables
  • Directoriobootstrap Bootstrap configuration for remote state
    • main.tf S3 bucket and policies for state storage
    • providers.tf AWS provider configuration
    • variables.tf Bootstrap variable definitions
  • Directorioscripts Node helpers run by the nx bootstrap, bootstrap-destroy and init targets
    • aws-config.ts Resolves account + region via the AWS SDK credential chain
    • bootstrap.ts Pulls/pushes the bootstrap tfstate and runs terraform apply
    • bootstrap-destroy.ts Empties the state bucket and runs terraform destroy
    • init.ts Runs terraform init with the S3 backend config
    • env.ts Points terraform init at the shared provider cache
  • checkov.yml Checkov configuration, including the checks to skip
  • project.json Project configuration and build targets
type = library

Para proyectos de biblioteca (--type=library), el generador crea una estructura más simple para módulos Terraform reutilizables:

  • Directoriosrc
    • main.tf Main Terraform module file
  • checkov.yml Checkov configuration, including the checks to skip
  • project.json Project configuration and build targets

Puedes comenzar a escribir tu infraestructura Terraform dentro de src/main.tf, por ejemplo:

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

Ten en cuenta que el bucket S3 anterior fallaría el escaneo de seguridad de Checkov, que verifica que el bucket tenga habilitadas las configuraciones de seguridad apropiadas.

Si quisieras ejecutar un módulo desde un proyecto separado (lib), podrías hacerlo de la siguiente manera:

module "lib_module" {
source = "../../path/to/my-lib/src"
}

Esto actualizará automáticamente el grafo de Nx para agregar una dependencia entre tu aplicación consumidora y tu lib.

Configura variables específicas del entorno en los archivos src/env/*.tfvars.

Para agregar nuevos entornos, crea un nuevo archivo src/env/<environment>.tfvars con las variables específicas del entorno y agrega nuevas entradas para apply, destroy, init, plan en el project.json para la nueva configuración de entorno. Por ejemplo, supongamos que queremos agregar un entorno prod:

# Production environment variables
environment = "prod"
aws_region = "us-west-2"
type = application

Bootstrap de Estado Remoto (Solo Proyectos Application)

Sección titulada «Bootstrap de Estado Remoto (Solo Proyectos Application)»

Antes de desplegar tu infraestructura, necesitarás hacer el bootstrap del backend de estado remoto. Esto crea un bucket S3 para almacenar tus archivos de estado de Terraform:

Terminal window
pnpm nx bootstrap tf-infra

Los targets disponibles dependen del tipo de tu proyecto:

Targets Comunes (Tanto Application como Library)

Sección titulada «Targets Comunes (Tanto Application como Library)»

Puedes validar tu configuración de Terraform usando el target validate:

Terminal window
pnpm nx validate tf-infra

Los proyectos Terraform usan terraform fmt para verificar el formato.

Para invocar el linter y verificar tu proyecto, puedes ejecutar el target lint.

Terminal window
pnpm nx lint tf-infra

La mayoría de los problemas de linting o formato se pueden corregir automáticamente ejecutando con el argumento --configuration=fix.

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

De manera similar, si deseas corregir todos los problemas de lint en todos los paquetes de tu workspace, puedes ejecutar:

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

Para evitar que los problemas de linting te ralenticen durante el desarrollo (particularmente si tienes problemas no auto-corregibles en tu proyecto), puedes ejecutar una compilación con la configuración skip-lint:

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

Esto omite la verificación de formato por completo durante la compilación.

Ejecuta verificaciones de seguridad en tu infraestructura usando Checkov con el target checkov:

Terminal window
pnpm nx checkov tf-infra

Encontrarás los resultados de tus pruebas de seguridad en la carpeta raíz dist, bajo dist/packages/<my-terraform-project>/checkov.

Checkov se ejecuta como parte de build.

Las verificaciones se configuran en el checkov.yml del proyecto. Agrega un id de verificación a skip-check para suprimirlo en todo el proyecto:

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

Para suprimir una verificación para un solo recurso, agrega un comentario #checkov:skip=<id>:<reason> dentro del bloque del recurso:

resource "aws_s3_bucket" "example" {
#checkov:skip=CKV_AWS_18:Access logging not required for this bucket
bucket = "example"
}

El target test ejecuta el framework de pruebas nativo de Terraform sobre cualquier archivo .tftest.hcl en tu proyecto:

Terminal window
pnpm nx test tf-infra

Un proyecto sin archivos de prueba es un éxito sin operación, por lo que puedes agregar pruebas cuando las necesites. build ejecuta este target, por lo que tus pruebas se ejecutan como parte de una compilación normal.

Cada bloque run evalúa tu configuración. Usa command = plan para verificar qué haría Terraform (esto expande todo el grafo de módulos, por lo que captura errores en tiempo de planificación que validate no puede), o command = apply para crear recursos reales y hacer aserciones sobre sus salidas. Declarar mock_provider significa que no se realizan llamadas a la API y no se necesitan credenciales de AWS, lo que mantiene las pruebas plan rápidas y seguras para ejecutar en 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"
}
}

Establece cada variable que tu configuración requiere en el bloque variables, de lo contrario la ejecución falla con “has a required variable … with no set value”.

Cada target que ejecuta terraform init reutiliza un caché de proveedores bajo .terraform/plugin-cache en la raíz de tu workspace, por lo que los proveedores se descargan una vez en lugar de en cada ejecución. Cada proyecto obtiene su propio directorio allí: dos ejecuciones de terraform init llenando un caché al mismo tiempo pueden calcular cada una un hash diferente para el mismo proveedor, que terraform luego rechaza contra tu .terraform.lock.hcl. Consulta la documentación de Terraform para más información.

Establece TF_PLUGIN_CACHE_DIR en tu entorno para apuntar el script init proporcionado a un caché que administres tú mismo — un volumen compartido entre workspaces, por ejemplo. Ten en cuenta que el target test lee su ruta desde project.json, así que cámbialo allí también.

type = application

Los siguientes targets solo están disponibles para proyectos de tipo application:

Antes de aplicar cambios, puedes ver qué hará Terraform ejecutando el target plan:

Terminal window
pnpm nx plan tf-infra

Esto creará un archivo de plan en dist/packages/<my-terraform-project>/terraform/dev.tfplan.

plan depende de assemble, por lo que produce los artefactos que tus módulos referencian, como los bundles de Lambda y los metadatos de operaciones generados, sin ejecutar las compuertas de lint, test y type-check.

Inicializa tu directorio de trabajo de Terraform con el target init:

Terminal window
pnpm nx run tf-infra:init

Después de planificar, puedes desplegar tu infraestructura a AWS usando el target apply:

Terminal window
pnpm nx apply tf-infra

Recupera valores de salida de tu configuración de Terraform:

Terminal window
pnpm nx output tf-infra

Cuando necesites desmantelar tu infraestructura, usa el target destroy:

Terminal window
pnpm nx destroy tf-infra

Para limpiar los recursos de bootstrap (bucket S3 para almacenamiento de estado):

Terminal window
pnpm nx bootstrap-destroy tf-infra

Esto vacía el bucket de estado antes de destruirlo, y resuelve la región desde la cadena de credenciales del AWS SDK, por lo que se ejecuta sin supervisión en CI.

Para más información sobre Terraform, consulta la Documentación de Terraform y la Documentación del Proveedor AWS.