Claude Code × AWS CloudFormation/CDK Guía Completa | Genera Infraestructura como Código Automáticamente
Acelera la infraestructura AWS como código con Claude Code. Código funcional para plantillas CloudFormation, stacks CDK TypeScript y diseño multi-stack, basado en la experiencia real de producción de Masa.
“Odio tener que hacer clic en la consola de AWS cada vez que quiero configurar infraestructura” — si alguna vez te has sentido así, no estás solo. CloudFormation y CDK hacen que la infraestructura sea reproducible mediante código, pero escribir esas plantillas consume tiempo.
Yo gestiono la infraestructura de este sitio (Cloudflare Pages + Workers + D1) con Claude Code, y para la infraestructura de AWS en producción también dejo que Claude Code genere las plantillas de CloudFormation/CDK. Las plantillas que antes tardaban horas ahora se terminan en 1/5 del tiempo.
CloudFormation vs CDK: ¿Cuál elegir?
CloudFormation: Servicio nativo de AWS que describe infraestructura en JSON/YAML
CDK (Cloud Development Kit): Framework que describe infraestructura en TypeScript/Python
y la sintetiza a CloudFormation
| Comparación | CloudFormation | CDK |
|---|---|---|
| Lenguaje | JSON / YAML | TypeScript, Python, Java, etc. |
| Seguridad de tipos | Ninguna | Excelente (totalmente type-safe con TypeScript) |
| Reutilización | Baja (copiar-pegar) | Alta (abstraída con clases y funciones) |
| Curva de aprendizaje | Baja | Media |
| Compatibilidad con Claude Code | Excelente | Sobresaliente |
Para nuevos proyectos, se recomienda ampliamente CDK TypeScript. Tiene una compatibilidad sobresaliente con Claude Code y, combinado con el autocompletado de tipos, produce código de alta calidad.
Paso 1: Convertir recursos AWS existentes a CloudFormation
Un patrón para cuando quieres codificar un entorno AWS existente después del hecho.
claude -p "
Convierte la siguiente configuración AWS en una plantilla CloudFormation (YAML).
[Configuración actual]
- VPC: 10.0.0.0/16, 2 subredes públicas, 2 subredes privadas
- EC2: t3.medium, Amazon Linux 2023, en subred pública
- RDS: MySQL 8.0, db.t3.micro, en subred privada
- ALB: HTTPS (certificado ACM), reenvío a EC2
- Grupos de seguridad: permitir 443 desde ALB, permitir 3306 desde EC2 a RDS
[Requisitos]
- Entorno (dev/staging/prod) conmutable mediante parámetro
- Anteponer el nombre del entorno a los nombres de los recursos
- Mostrar el nombre DNS del ALB en los Outputs de CloudFormation
"
Plantilla CloudFormation generada (extracto):
AWSTemplateFormatVersion: "2010-09-09"
Description: "Web Application Infrastructure"
Parameters:
Environment:
Type: String
AllowedValues: [dev, staging, prod]
Default: dev
DBPassword:
Type: String
NoEcho: true # Ocultar la contraseña
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${Environment}-vpc"
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
AvailabilityZone: !Select [0, !GetAZs ""]
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${Environment}-public-1"
# Grupo de seguridad del ALB
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: ALB Security Group
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Outputs:
ALBDnsName:
Value: !GetAtt ApplicationLoadBalancer.DNSName
Export:
Name: !Sub "${Environment}-alb-dns"
Paso 2: Construir un stack serverless con CDK
Con CDK se escribe en TypeScript, lo que facilita la reutilización de lógica.
# Inicializar proyecto CDK
mkdir my-infra && cd my-infra
npx cdk init app --language typescript
claude -p "
Implementa la siguiente configuración serverless en CDK TypeScript en lib/my-infra-stack.ts.
[Configuración]
- API Gateway (REST API) + Lambda (Node.js 20)
- Tabla DynamoDB (PAY_PER_REQUEST)
- Bucket S3 (privado, versionado habilitado)
- CloudFront (origen S3, soporte de dominio personalizado)
- Pasar nombre de tabla DynamoDB y nombre de bucket S3 como variables de entorno a Lambda
- Adjuntar automáticamente rol IAM de mínimo privilegio a Lambda
Etiquetar todos los recursos apropiadamente,
y habilitar protección contra eliminación en producción (NODE_ENV=production).
"
Código CDK generado:
// lib/my-infra-stack.ts
import * as cdk from "aws-cdk-lib";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
import * as s3 from "aws-cdk-lib/aws-s3";
import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
import * as origins from "aws-cdk-lib/aws-cloudfront-origins";
export class MyInfraStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const isProd = process.env.NODE_ENV === "production";
// Tabla DynamoDB
const table = new dynamodb.Table(this, "AppTable", {
partitionKey: { name: "PK", type: dynamodb.AttributeType.STRING },
sortKey: { name: "SK", type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
pointInTimeRecovery: true,
deletionProtection: isProd,
removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
});
// Bucket S3
const bucket = new s3.Bucket(this, "AssetsBucket", {
versioned: true,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
deletionProtection: isProd,
removalPolicy: isProd ? cdk.RemovalPolicy.RETAIN : cdk.RemovalPolicy.DESTROY,
});
// Función Lambda
const apiLambda = new lambda.Function(this, "ApiLambda", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
code: lambda.Code.fromAsset("src/lambda"),
environment: {
TABLE_NAME: table.tableName,
BUCKET_NAME: bucket.bucketName,
NODE_ENV: process.env.NODE_ENV ?? "development",
},
timeout: cdk.Duration.seconds(30),
memorySize: 512,
});
// Otorgar permisos de mínimo privilegio a Lambda
table.grantReadWriteData(apiLambda);
bucket.grantReadWrite(apiLambda);
// API Gateway
const api = new apigateway.RestApi(this, "AppApi", {
restApiName: "MyApp API",
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS,
allowMethods: apigateway.Cors.ALL_METHODS,
},
});
api.root.addProxy({
defaultIntegration: new apigateway.LambdaIntegration(apiLambda),
});
// CloudFront
const distribution = new cloudfront.Distribution(this, "Distribution", {
defaultBehavior: {
origin: new origins.S3Origin(bucket),
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
},
});
// Salida
new cdk.CfnOutput(this, "ApiUrl", { value: api.url });
new cdk.CfnOutput(this, "CloudFrontUrl", { value: distribution.distributionDomainName });
}
}
Paso 3: Actualizar stacks existentes y revisar diferencias
# Revisar diferencias antes del despliegue
npx cdk diff
# Pedir a Claude Code que explique las diferencias
claude -p "
Lee la salida de cdk diff y explica en español qué cambió.
Presta especial atención a los cambios en grupos de seguridad y políticas IAM.
$(npx cdk diff 2>&1)
"
Paso 4: Diseñar una arquitectura multi-stack
La infraestructura a escala de producción se gestiona dividiéndola en múltiples stacks.
claude -p "
Diseña la siguiente configuración multi-stack en CDK TypeScript.
[Estrategia de división de stacks]
- NetworkStack: VPC, subredes, grupos de seguridad
- DatabaseStack: RDS, ElastiCache (depende de NetworkStack)
- ApplicationStack: ECS, ALB, AutoScaling (depende de NetworkStack, DatabaseStack)
- MonitoringStack: Dashboards CloudWatch, alarmas, notificaciones SNS
Incluir dependencias entre stacks y cómo usar CfnOutput / Fn.importValue.
"
// bin/app.ts
import * as cdk from "aws-cdk-lib";
import { NetworkStack } from "../lib/network-stack";
import { DatabaseStack } from "../lib/database-stack";
import { ApplicationStack } from "../lib/application-stack";
import { MonitoringStack } from "../lib/monitoring-stack";
const app = new cdk.App();
const env = { account: process.env.CDK_ACCOUNT, region: "us-east-1" };
const network = new NetworkStack(app, "NetworkStack", { env });
const database = new DatabaseStack(app, "DatabaseStack", { env, vpc: network.vpc });
const application = new ApplicationStack(app, "ApplicationStack", {
env,
vpc: network.vpc,
database: database.cluster,
});
new MonitoringStack(app, "MonitoringStack", {
env,
alb: application.alb,
database: database.cluster,
});
Paso 5: Dejar que Claude Code maneje el debugging de CloudFormation/CDK
Claude Code también puede ayudar a resolver fallos de despliegue.
claude -p "
CDK deploy está fallando con el siguiente error.
Explica la causa y cómo solucionarlo:
$(npx cdk deploy 2>&1 | tail -30)
"
Patrones de fallo comunes:
- ROLLBACK_COMPLETE: Despliegue anterior falló, dejando el stack roto → ejecutar
cdk destroyy volver a desplegar - UPDATE_ROLLBACK_FAILED: Conflicto con cambios manuales → resolver manualmente en la consola AWS
- Resource already exists: Colisión de nombres con un recurso existente → cambiar el nombre del recurso o importarlo
4 errores comunes a evitar
1. Eludir la protección contra eliminación con cdk destroy
En entornos de desarrollo, los recursos permanecerán después de cdk destroy si no se establece removalPolicy: DESTROY. En producción, usar RETAIN para prevenir eliminaciones accidentales.
2. Ignorar la detección de drift en CloudFormation
Cuando cambias recursos manualmente en la consola AWS, CloudFormation queda desincronizado con la realidad (drift). Ejecuta la detección de drift en la consola CloudFormation una vez al mes.
3. Escribir secretos directamente en las plantillas
# Mal: la contraseña queda en la plantilla
DBPassword: "mysecretpassword"
# Bien: obtener de Secrets Manager o Parameter Store
DBPassword: !Sub "{{resolve:secretsmanager:prod/db-password}}"
4. Descuidar el versionado fijo de CDK
Si las versiones de CDK no están alineadas en el equipo en package.json, aparecerán diferencias. Commitear package-lock.json para asegurar que todos usen la misma versión.
Resumen
| Tarea | Contribución de Claude Code |
|---|---|
| Generación de CloudFormation | YAML completo solo con describir los requisitos |
| Implementación CDK | Código de infraestructura type-safe en TypeScript |
| Diseño de stacks | Arquitectura de dependencias multi-stack |
| Explicación de diffs | Salida de cdk diff explicada en español |
| Debugging | Causa raíz y solución a partir de logs de error |
La infraestructura como código es algo que todos sabemos que deberíamos hacer pero seguimos aplazando. Con Claude Code, solo describes “la configuración AWS que necesito” y la plantilla está lista — reduciendo dramáticamente la barrera para adoptar IaC.
Artículos relacionados
- Claude Code × AWS Lambda Guía Completa
- Claude Code × AWS IAM Guía Completa
- Claude Code × AWS DynamoDB Guía Completa
Referencias
Lleva tu flujo con Claude Code al siguiente nivel
50 plantillas de prompts probadas en producción, listas para copiar y pegar en Claude Code.
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
Claude Code × Amazon Bedrock Guía Completa | Ejecutar Claude en Producción con AWS
Guía completa para usar Amazon Bedrock con Claude Code. Desde autenticación IAM, streaming, integración con Lambda, implementación RAG hasta optimización de costos, basada en la experiencia real de producción de Masa.
Claude Code × AWS CodePipeline/CodeBuild Guía Completa | Construcción automática de pipelines CI/CD
Construye automáticamente CI/CD con AWS CodePipeline y CodeBuild usando Claude Code. Ejemplos reales de diseño de pipelines, generación de buildspec.yml, automatización de pruebas e infraestructura CDK.
Claude Code × AWS CloudWatch Guía Completa | Análisis de Logs, Alarmas y Dashboards Automáticos
Optimiza AWS CloudWatch con Claude Code. Código práctico para análisis de patrones de logs, configuración automática de alarmas, dashboards de métricas e investigación de incidentes.