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.
Generar un Proyecto Terraform
Sección titulada «Generar un Proyecto Terraform»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 yarn nx g @aws/nx-plugin:terraform#project npx nx g @aws/nx-plugin:terraform#project bunx nx g @aws/nx-plugin:terraform#project- Instale el Nx Console VSCode Plugin si aún no lo ha hecho
- Abra la consola Nx en VSCode
- Haga clic en
Generate (UI)en la sección "Common Nx Commands" - Busque
@aws/nx-plugin - terraform#project - Complete los parámetros requeridos
- Haga clic en
Generate
Construya su comando5
Requerido
Opciones
Sección titulada «Opciones»nameRequeridostringEl nombre del proyecto.
typeenumPredeterminado:applicationSi esto es una lib de terraform (módulos reutilizables) o app (desplegable).
applicationlibrarydirectorystringPredeterminado:packagesEl directorio del nuevo proyecto.
subDirectorystringEl subdirectorio en el que se coloca el proyecto. Por defecto, este es el nombre del proyecto.
preferInstallDependenciesbooleanPredeterminado:trueSi 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.
Salida del Generador
Sección titulada «Salida del Generador»El generador crea diferentes estructuras de archivos dependiendo del tipo de proyecto:
Tipo Application
Sección titulada «Tipo 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-destroyandinittargets- 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 initwith the S3 backend config - env.ts Points
terraform initat the shared provider cache
- checkov.yml Checkov configuration, including the checks to skip
- project.json Project configuration and build targets
Tipo Library
Sección titulada «Tipo 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
Implementar tu Infraestructura Terraform
Sección titulada «Implementar tu Infraestructura Terraform»Puedes comenzar a escribir tu infraestructura Terraform dentro de src/main.tf, por ejemplo:
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"}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.
Dependencias entre proyectos
Sección titulada «Dependencias entre proyectos»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.
Configuración de Entorno
Sección titulada «Configuración de Entorno»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 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 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:
pnpm nx bootstrap tf-infrayarn nx bootstrap tf-infranpx nx bootstrap tf-infrabunx nx bootstrap tf-infraTargets Disponibles
Sección titulada «Targets Disponibles»Los targets disponibles dependen del tipo de tu proyecto:
Targets Comunes (Tanto Application como Library)
Sección titulada «Targets Comunes (Tanto Application como Library)»Validar tu Infraestructura
Sección titulada «Validar tu Infraestructura»Puedes validar tu configuración de Terraform usando el target validate:
pnpm nx validate tf-infrayarn nx validate tf-infranpx nx validate tf-infrabunx nx validate tf-infraLinting
Sección titulada «Linting»Los proyectos Terraform usan terraform fmt para verificar el formato.
Ejecutar el Linter
Sección titulada «Ejecutar el Linter»Para invocar el linter y verificar tu proyecto, puedes ejecutar el target lint.
pnpm nx lint tf-infrayarn nx lint tf-infranpx nx lint tf-infrabunx nx lint tf-infraCorregir Problemas de Lint
Sección titulada «Corregir Problemas de Lint»La mayoría de los problemas de linting o formato se pueden corregir automáticamente ejecutando con el argumento --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=fixDe manera similar, si deseas corregir todos los problemas de lint en todos los paquetes de tu workspace, puedes ejecutar:
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=fixOmitir Problemas de Lint
Sección titulada «Omitir Problemas de Lint»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:
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-lintEsto omite la verificación de formato por completo durante la compilación.
Pruebas de Seguridad
Sección titulada «Pruebas de Seguridad»Ejecuta verificaciones de seguridad en tu infraestructura usando Checkov con el target checkov:
pnpm nx checkov tf-infrayarn nx checkov tf-infranpx nx checkov tf-infrabunx nx checkov tf-infraEncontrará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:
skip-check: - CKV_AWS_115 # Concurrent execution limit - CKV_AWS_116 # Dead Letter QueuePara 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"}Ejecutar Pruebas de Terraform
Sección titulada «Ejecutar Pruebas de Terraform»El target test ejecuta el framework de pruebas nativo de Terraform sobre cualquier archivo .tftest.hcl en tu proyecto:
pnpm nx test tf-infrayarn nx test tf-infranpx nx test tf-infrabunx nx test tf-infraUn 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:
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.
Targets Solo para Application
Sección titulada «Targets Solo para Application»Los siguientes targets solo están disponibles para proyectos de tipo application:
Planificar tu Infraestructura
Sección titulada «Planificar tu Infraestructura»Antes de aplicar cambios, puedes ver qué hará Terraform ejecutando el target plan:
pnpm nx plan tf-infrayarn nx plan tf-infranpx nx plan tf-infrabunx nx plan tf-infraEsto 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.
Inicializar Terraform
Sección titulada «Inicializar Terraform»Inicializa tu directorio de trabajo de Terraform con el target init:
pnpm nx run tf-infra:inityarn nx run tf-infra:initnpx nx run tf-infra:initbunx nx run tf-infra:initDesplegar a AWS
Sección titulada «Desplegar a AWS»Después de planificar, puedes desplegar tu infraestructura a AWS usando el target apply:
pnpm nx apply tf-infrayarn nx apply tf-infranpx nx apply tf-infrabunx nx apply tf-infraObtener Outputs
Sección titulada «Obtener Outputs»Recupera valores de salida de tu configuración de Terraform:
pnpm nx output tf-infrayarn nx output tf-infranpx nx output tf-infrabunx nx output tf-infraDestruir Infraestructura
Sección titulada «Destruir Infraestructura»Cuando necesites desmantelar tu infraestructura, usa el target destroy:
pnpm nx destroy tf-infrayarn nx destroy tf-infranpx nx destroy tf-infrabunx nx destroy tf-infraDestruir Recursos de Bootstrap
Sección titulada «Destruir Recursos de Bootstrap»Para limpiar los recursos de bootstrap (bucket S3 para almacenamiento de estado):
pnpm nx bootstrap-destroy tf-infrayarn nx bootstrap-destroy tf-infranpx nx bootstrap-destroy tf-infrabunx nx bootstrap-destroy tf-infraEsto 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.
Más Información
Sección titulada «Más Información»Para más información sobre Terraform, consulta la Documentación de Terraform y la Documentación del Proveedor AWS.