energy-systems-and-sustainability
Implementación de infraestructuras automatizadas para aplicaciones sin servidores con Terraform
Table of Contents
Esta infraestructura sin servidor se convierte en un reto de implementación, que permite la implementación de herramientas de diseño, y que se pueden utilizar de forma ininterrumpida. Sin embargo, la ejecución de aplicaciones sin servidor en la producción implica mucho más que escribir código de función. Necesita proporcionar y gestionar decenas de recursos de nube: las redes de archivos de infraestructura, las aplicaciones de códigos de administración de archivos, las configuraciones de registro y los componentes de redes.
¿Qué es Terraform?
Terraform es una herramienta IaC de código abierto creada por HashiCorp que le permite proporcionar y gestionar infraestructura a través de múltiples proveedores de nube utilizando un lenguaje de configuración declarativo conocido como HCL (HashiCorp Configuration Language). En lugar de escribir scripts imperativos que ejecutan comandos paso a paso, usted declara el estado deseado de su infraestructura — qué recursos desea, sus propiedades, y cómo se relacionan entre sí— y Terraform determina las acciones necesarias para alcanzar ese estado.
En el corazón de Terraform es el plan de ejecución. Antes de realizar cambios, Terraform compara su configuración con el estado actual de la infraestructura y produce un plan detallado de lo que se creará, actualizará o destruirá. Este plan puede ser revisado (y, en tuberías CI/CD, aprobado) antes de que se aplique, dándole un bucle de retroalimentación segura que previene cambios no deseados. Terraform también rastrea los recursos en un archivo de estado, que mapea la configuración para la nube.
Terraform soporta a cientos de proveedores, incluyendo todas las principales plataformas de nube (AWS, Azure, Google Cloud), así como servicios de SaaS como Cloudflare, Datadog y GitHub. Para aplicaciones sin servidor en AWS, usted utilizará normalmente el AWS proveedor para definir funciones de Lambda, API de API Gateway REST de la piscina, cada tablas de DynamoD queB
Por qué las aplicaciones sin servidor necesitan infraestructura como código
Las aplicaciones sin servidor consisten en muchos servicios pequeños y diseñados para fines que comunican de forma asincrónica o sincronizada. Una arquitectura típica impulsada por eventos puede incluir una API Gateway que recibe solicitudes HTTP, una función Lambda para procesarlos, una tabla DynamoDB para almacenar resultados, y una cola de SQS para amortiguar trabajo para una segunda función Lambda.
- Inconsistencia: Diferentes entornos (dev, estadificación, prod) inevitablemente se desvían cuando se crean manualmente.
- No historia de la versión: ¿Quién cambió la capacidad de lectura de DynamoDB? ¿Cuándo? ¿Por qué? Sin código, pierdes auditabilidad.
- pesadilla de la recreación: Después de un desastre, tendrías que reconfigurar todo desde cero, esperando que recuerdes cada escenario.
- Desechos temporales: Al hacer clic a través de la consola para cada recurso se consumen horas que deben ir a la lógica de aplicación.
IaC resuelve estos problemas convirtiendo la infraestructura en software. Cada cambio es una petición de tirada. Cada entorno es un despliegue repetible. Y toda su arquitectura puede ser desgarrada y reconstruida en minutos. Para aplicaciones sin servidor, donde la proposición de valor es velocidad y agilidad, IaC no es opcional, es la base de un flujo de trabajo de producción confiable.
Beneficios clave de usar Terraform para sin servidores
Aunque cualquier herramienta IaC podría ser utilizada para gestionar la infraestructura sin servidor, Terraform ofrece ventajas distintas que se alinean bien con las necesidades de los equipos sin servidor.
Automatización del ciclo de vida completo
Terraform maneja no sólo el suministro, sino también la actualización y destrucción de recursos. Cuando usted necesita cambiar el tamaño de la memoria de una función Lambda o el atributo TTL de una tabla DynamoDB, simplemente actualiza la configuración y ejecuta . Cuando se hace con un recurso, el mismo código que lo creó la limpieza. Esto es especialmente valioso en entornos efímeros — como previsualización de despliegues para cada pila puede hacer más adelante
Gestión de la Dependencia
Las arquitecturas sin servidor tienen dependencias intrincadas. Una función Lambda depende de un papel IAM, que puede depender de una política, que puede depender de una tabla DynamoDB ARN. Terraform construye un gráfico de recursos de sus declaraciones y determina automáticamente el orden correcto de las operaciones. Crea recursos antes de que se refieran y espera que las dependencias estén disponibles. Esto le libera de escribir scripts propensas errores que secuencia comandos.
Multi-Environment Consistency
Utilizando espacios de trabajo o estructuras de directorio Terraform, puedes reutilizar la misma configuración en múltiples entornos con diferentes valores variables. La configuración de una función Lambda puede ser idéntica en todo devoto, estadificación y producción, excepto en variables específicas para el medio ambiente como nombres de tablas, niveles de registro o configuración VPC. Esto asegura que la infraestructura de producción es exactamente lo que se probó en el estadificación.
Control del Estado Granular
Terraform le permite almacenar el estado remotamente en backends como S3 (con bloqueo DynamoDB), Terraform Cloud o HashiCorp Consul. El estado remoto permite la colaboración del equipo: múltiples ingenieros pueden aplicar cambios a la misma infraestructura sin conflictos. Para equipos sin servidores que implementan continuamente, es esencial una gestión estatal robusta.
Empezar con Terraform para el despliegue sin servidores
Caminemos a través de la configuración de una aplicación completa sin servidor usando Terraform en AWS. Nuestro ejemplo expondrá una API REST simple a través de API Gateway que activa una función Lambda, que escribe datos a una tabla DynamoDB. También cubriremos los permisos IAM requeridos.
Prerrequisitos
- Terraform instalado (]download)
- Cuenta AWS con credenciales configuradas (a través de variables ambientales o )
- Node.js instalado (para compilar el código Lambda)
Estructura del proyecto
serverless-terraform/
├── main.tf
├── variables.tf
├── outputs.tf
├── lambda/
│ └── index.js
└── terraform.tfvars
1. Define el Proveedor de Terraform
En , configura el proveedor de AWS y especifica la región:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "serverless-app/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
}
provider "aws" {
region = var.aws_region
}
2. Crear papel de IAM para Lambda
data "aws_iam_policy_document" "lambda_assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
resource "aws_iam_role" "lambda_exec" {
name = "serverless-lambda-role"
assume_role_policy = data.aws_iam_policy_document.lambda_assume_role.json
}
resource "aws_iam_policy" "lambda_dynamodb_policy" {
name = "lambda-dynamodb-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:UpdateItem"]
Effect = "Allow"
Resource = aws_dynamodb_table.items.arn
},
{
Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"]
Effect = "Allow"
Resource = "*"
}
]
})
}
resource "aws_iam_role_policy_attachment" "lambda_policy_attach" {
role = aws_iam_role.lambda_exec.name
policy_arn = aws_iam_policy.lambda_dynamodb_policy.arn
}
3. Despliegue la tabla DynamoDB
resource "aws_dynamodb_table" "items" {
name = "items"
billing_mode = "PAY_PER_REQUEST"
hash_key = "id"
attribute {
name = "id"
type = "S"
}
tags = {
Environment = var.environment
}
}
4. Paquete y Despliegue la función de la lambda
Primero, crear una función simple Lambda en :
exports.handler = async (event) => {
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const id = event.pathParameters.id;
const params = {
TableName: process.env.TABLE_NAME,
Item: { id, timestamp: Date.now(), data: event.body }
};
await dynamodb.put(params).promise();
return {
statusCode: 200,
body: JSON.stringify({ id })
};
};
Luego, en su configuración Terraform, consulte el código de función:
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "${path.module}/lambda"
output_path = "${path.module}/lambda_function_payload.zip"
}
resource "aws_lambda_function" "api_handler" {
filename = data.archive_file.lambda_zip.output_path
function_name = "serverless-api-handler"
role = aws_iam_role.lambda_exec.arn
handler = "index.handler"
runtime = "nodejs18.x"
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
environment {
variables = {
TABLE_NAME = aws_dynamodb_table.items.name
}
}
}
5. Exponer la Lambda a través de la puerta de la API
resource "aws_api_gateway_rest_api" "api" {
name = "serverless-api"
}
resource "aws_api_gateway_resource" "items" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_rest_api.api.root_resource_id
path_part = "items"
}
resource "aws_api_gateway_resource" "item" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_resource.items.id
path_part = "{id}"
}
resource "aws_api_gateway_method" "put_item" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.item.id
http_method = "PUT"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "lambda" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.item.id
http_method = aws_api_gateway_method.put_item.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.api_handler.invoke_arn
}
resource "aws_lambda_permission" "apigw" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.api_handler.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*"
}
resource "aws_api_gateway_deployment" "prod" {
depends_on = [aws_api_gateway_integration.lambda]
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "prod"
}
6. Definir los productos
En , exponga el punto final de la API:
output "api_endpoint" {
value = "${aws_api_gateway_deployment.prod.invoke_url}/items/"
}
7. Aplicar
terraform init
terraform plan
terraform apply
Después de aplicar, puede emitir una solicitud PUT al endpoint con un cuerpo JSON. La función Lambda escribe los datos a DynamoDB. Para derribar toda la pila, ejecute .
Proyectos Terraform para Servidores
Las aplicaciones sin servidor en el mundo real son demasiado grandes para un solo archivo de configuración. Adoptar una estructura de proyecto escalable es crítico.
Utilice módulos para encapsular componentes reutilizables
Los módulos Terraform le permiten agrupar recursos en unidades lógicas. Para los sin servidor, puede crear módulos para:
- Un módulo base de función Lambda (con función IAM, permisos básicos de CloudWatch y configuración opcional VPC)
- Un módulo de integración de API Gateway + Lambda
- Un módulo de mesa DynamoDB con atributos estandarizados y autoescalamiento
- Un módulo de cola SQS con colas de letras muertas
Los módulos pueden almacenarse en su propio repositorio Git o publicarse en el Registro Terraform. Simplifican las configuraciones específicas del medio ambiente: instantáneamente un módulo con diferentes variables por medio ambiente.
Medios separados con directorios o espacios de trabajo
Existen dos enfoques comunes para la gestión de entornos:
- ]Directoría por medio ambiente:] Crear carpetas como , , , cada una con su propio y posiblemente una . Esto aísla los archivos estatales y evita cambios accidentales de entorno cruzado.
- ]Terraform Workspaces: Usa la función de espacio de trabajo incorporado para crear instancias nombradas de la misma configuración. Los espacios de trabajo son más ligeros pero pueden llegar a ser confusos cuando se trata de múltiples equipos.
Para la mayoría de los equipos sin servidor, el enfoque del directorio es más claro porque hace que los límites del entorno sean explícitos en la base de código.
Estado remoto con bloqueo
Nunca almacene el estado localmente para proyectos de equipo. Utilice un backend S3 con bloqueo DynamoDB. El cubo S3 tiene el archivo estatal, y DynamoDB proporciona cerraduras de consistencia para que sólo una funciona en un momento. Ejemplo configuración de backend se mostró antes. Asegúrese de que el cubo S3 y la mesa DynamoDB se crean fuera de Terraform (bootstrap them con un script separado o use Terraform state management).
Gestionar secretos de forma segura
Las aplicaciones sin servidor a menudo requieren secretos como contraseñas de bases de datos, claves de API o fichas de firma JWT. Nunca codificar duro estos en los configs de Terraform. En lugar de eso, use:
- AWS Secrets Manager o SSM Parameter Store, referenciado a través de o fuentes de datos
- Proveedor de Vault para buscar secretos dinámicos
- Archivos variables cifrados específicos para el medio ambiente (por ejemplo, con herramientas como )
Mejores prácticas para la infraestructura automatizada con Terraform
Para maximizar la fiabilidad y la velocidad del equipo, siga estas prácticas probadas:
Control de versiones Todo
Todas las configuraciones Terraform, incluyendo los módulos, deben ser almacenadas en Git con mensajes de compromiso significativos. Etiqueta libera y utiliza sucursales para cambios. Esto proporciona una ruta de auditoría completa de quién cambió qué y cuándo.
Siempre Ejecutar Plan y Revisión
En el desarrollo local, siempre se ejecuta antes . En CI/CD, se requiere un paso de aprobación manual para las implementaciones de producción. Terraform Cloud y Atlantis son herramientas populares que integran los flujos de trabajo plan/apply en las solicitudes de tiradas.
Implementar CI/CD para Infraestructura
Usa un oleoducto que funciona y en solicitudes de tirada, luego ejecuta , y después de fusionarse— funciona . Para los sin servidor, puede realizar pruebas de integración después de la aplicación para verificar que los endpoints de API respondan correctamente.
Uso para detección de secreción
Incluso con CI/CD, alguien puede modificar manualmente un recurso a través de la consola. Programar regular se ejecuta (por ejemplo, nocturna) para detectar la deriva y alertar al equipo. Herramientas como la detección de deriva de Terraform Cloud pueden automatizar esto.
Prueba tus configuraciones de Terraform
El código de infraestructura de prueba de unidad es posible con herramientas como Terratest], una biblioteca Go que da vueltas a los recursos de nube reales, verifica su comportamiento y los desgarra. Para los sin servidor, puede desplegar pilas en cuentas de prueba aisladas, ejecutar pruebas HTTP contra la API y validar contenidos DynamoDB. Mientras escribe pruebas Terratest es una inversión, captura errores de configuración temprana.
Política de uso como código
Definir reglas de cumplimiento de toda la organización utilizando HashiCorp Sentinel (Cloud) o Agente de Política Abierta. Por ejemplo, requieren que todas las funciones de Lambda tengan habilitado el rastreo de X-Ray, o prevengan tablas públicas de DynamoDB. Estas políticas se aplican a tiempo de plan, haciendo que la seguridad y la gobernanza de costos sean sistemáticas.
Desafíos y soluciones comunes
Estado de bloqueo de archivos y conflictos
Cuando varios miembros del equipo funcionan simultáneamente, puede ocurrir la corrupción del estado. Solución: siempre utilice un backend que soporta bloqueo (S3 + DynamoDB) y nunca se ejecute directamente de ramas paralelas. Use tuberías CI/CD para serializar se aplica.
Manejo de grandes números de funciones de lambda
La gestión de funciones de 50+ Lambda en una sola configuración se vuelve poco inteligente. Solución: uso o con un mapa de definiciones de funciones. Mejor aún, organiza funciones en configuraciones separadas de Terraform que comparten fuentes de datos estatales. Por ejemplo, una configuración central de “core” exporta productos (DynamoDB nombres de tablas, SQS queue URLs) que importan [FLT]
Ordenación de dependencia en arquitecturas complejas
Aunque Terraform maneja la mayoría de las dependencias automáticamente, las dependencias circulares (por ejemplo, dos servicios que se refieren a las ARNs de los demás) pueden causar problemas. Solución: romper el ciclo introduciendo un tercer recurso (como un tema central de SNS) o utilizar bloques explícitos . Para los sin servidor, un patrón común es crear roles y políticas de IAM separadamente de funciones para evitar ciclos.
Implementación de Cambios en el Código de Lambda
Terraform está diseñado para infraestructura, no para implementar continuamente código de aplicación. Empujar nuevas versiones de Lambda re-applying Terraform cada vez es lento y no ideal para iteraciones de código rápido. Solución: separar el despliegue de infraestructura (creado una vez por medio) del despliegue de código. Utilice los conductos CI/CD que actualizan el código de función Lambda a través del código fuente AWS SDK o herramientas como el código sin servidor, mientras TerraLT.
Conclusión
El despliegue de infraestructuras automatizadas con Terraform trae el mismo rigor a la infraestructura sin servidor que los equipos de software aplican al código de aplicación. Al definir cada recurso en archivos HCL controlados por la versión, usted obtiene implementaciones repetibles, gestión de cambios seguros y rutas de auditoría completas. Un proyecto Terraform bien estructurado con módulos, estado remoto y integración CI/CD permite a los equipos gestionar cientos de funciones de Lambda, puntos finales de API y almacenes de datos sin perder tiempo de suministro manual.
A medida que las arquitecturas sin servidor siguen creciendo en complejidad —con flujos de trabajo impulsados por eventos, funciones de paso y infraestructura global distribuidas en múltiples regiones— la importancia de IaC robusto aumenta. Empezando con los patrones y ejemplos en este artículo, puedes construir una base que escala con tu aplicación y tu organización. La inversión inicial en la automatización de tu infraestructura sin servidor paga por sí misma muchas veces en errores reducidos, despliegues más rápidos y mayor confianza que tu entorno.