Use Cases

Claude Code × AWS Lambda Guía Completa | De la Generación de Funciones a la Automatización del Despliegue

Desarrolla funciones AWS Lambda a velocidad máxima con Claude Code. Tutorial completo con código real: generación de handlers, diseño de políticas IAM, automatización SAM, integraciones con API Gateway/S3/DynamoDB.

¿Has tenido estas experiencias al desarrollar con AWS Lambda? Las definiciones de tipo para los handlers son tediosas, tienes que buscar las políticas IAM cada vez, olvidaste cómo escribir las plantillas SAM… Claude Code resuelve todo esto de una vez.

Desde la implementación de funciones Lambda hasta la generación de políticas IAM, las pruebas locales y el despliegue en producción — cubrimos cada paso del desarrollo ultrarrápido de AWS Lambda con Claude Code usando ejemplos de código reales.

¿Por Qué Claude Code × AWS Lambda?

Las “partes tediosas” del desarrollo Lambda son casi en su totalidad código repetitivo (boilerplate).

  • Definiciones de tipo para funciones handler (APIGatewayProxyHandler, S3Handler …)
  • Manejo de errores y formatos de respuesta
  • Diseño de políticas IAM de mínimo privilegio
  • Escritura de plantillas SAM / CloudFormation
  • Configuración del entorno de pruebas local

Claude Code genera todo esto con una sola frase como “Quiero una Lambda que haga X”. Combinado con AWS CLI y SAM CLI, puedes ejecutar todo desde la generación de código hasta el despliegue de una sola vez.

Configuración del Entorno

# Verificar herramientas necesarias
aws --version        # AWS CLI v2
sam --version        # SAM CLI 1.100+
node --version       # Node.js 20+

# Configurar credenciales de AWS (si aún no están configuradas)
aws configure
# → Access Key ID, Secret Access Key, Region (us-east-1), Output (json)
<!-- Agregar a CLAUDE.md -->
## Configuración AWS
- Región predeterminada: us-east-1
- Runtime de Lambda: nodejs20.x
- Herramienta de despliegue: AWS SAM
- Directorio de código fuente: src/functions/
- Plantilla SAM: template.yaml
- Nombre del stack: my-app-{dev|staging|prod}

## Lineamientos de Política IAM
- Seguir estrictamente el principio de mínimo privilegio
- No usar comodines (*)
- Especificar los ARN de recursos de forma concreta

Ejemplo 1: API Gateway + Lambda (REST API)

El patrón más fundamental — una Lambda que recibe peticiones HTTP y las procesa.

Instrucciones para Claude Code

claude -p "
Cuando llegue una petición GET a /users/{userId},
recuperar la información del usuario de la tabla Users en DynamoDB y devolverla.
Implementar la función Lambda en TypeScript.

- Runtime: Node.js 20
- Nombre de tabla: UsersTable (recibido mediante variable de entorno)
- Manejo de errores: devolver respuestas 404/500 apropiadas
- Definiciones de tipo: usar @types/aws-lambda
- Salida a: src/functions/getUser/index.ts
"

Implementación Generada

// src/functions/getUser/index.ts
import {
  APIGatewayProxyHandler,
  APIGatewayProxyResult,
} from "aws-lambda";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, GetCommand } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({ region: process.env.AWS_REGION });
const ddb = DynamoDBDocumentClient.from(client);

const response = (statusCode: number, body: unknown): APIGatewayProxyResult => ({
  statusCode,
  headers: {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*",
  },
  body: JSON.stringify(body),
});

export const handler: APIGatewayProxyHandler = async (event) => {
  const userId = event.pathParameters?.userId;

  if (!userId) {
    return response(400, { error: "userId is required" });
  }

  try {
    const result = await ddb.send(
      new GetCommand({
        TableName: process.env.USERS_TABLE!,
        Key: { userId },
      })
    );

    if (!result.Item) {
      return response(404, { error: `User '${userId}' not found` });
    }

    return response(200, result.Item);
  } catch (err) {
    console.error("DynamoDB error:", err);
    return response(500, { error: "Internal server error" });
  }
};

La Plantilla SAM También Se Genera Automáticamente

# template.yaml (fragmento)
GetUserFunction:
  Type: AWS::Serverless::Function
  Properties:
    Handler: src/functions/getUser/index.handler
    Runtime: nodejs20.x
    Timeout: 10
    Environment:
      Variables:
        USERS_TABLE: !Ref UsersTable
    Policies:
      - DynamoDBReadPolicy:
          TableName: !Ref UsersTable
    Events:
      GetUserApi:
        Type: Api
        Properties:
          Path: /users/{userId}
          Method: GET

UsersTable:
  Type: AWS::DynamoDB::Table
  Properties:
    TableName: !Sub "${AWS::StackName}-users"
    BillingMode: PAY_PER_REQUEST
    AttributeDefinitions:
      - AttributeName: userId
        AttributeType: S
    KeySchema:
      - AttributeName: userId
        KeyType: HASH

Ejemplo 2: Lambda con Trigger de Evento S3

Una Lambda que se activa con la carga de archivos para ejecutar procesamientos.

// src/functions/generateThumbnail/index.ts
import { S3Handler } from "aws-lambda";
import { S3Client, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
import sharp from "sharp";

const s3 = new S3Client({ region: process.env.AWS_REGION });

export const handler: S3Handler = async (event) => {
  const record = event.Records[0];
  const bucket = record.s3.bucket.name;
  const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, " "));

  // Ignorar el prefijo thumbnails/ (prevenir bucle infinito)
  if (key.startsWith("thumbnails/")) return;

  const { Body } = await s3.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
  const buffer = Buffer.from(await Body!.transformToByteArray());

  const thumbnail = await sharp(buffer)
    .resize(200, 200, { fit: "cover" })
    .webp({ quality: 85 })
    .toBuffer();

  const thumbnailKey = `thumbnails/${key.replace(/\.[^.]+$/, ".webp")}`;
  await s3.send(
    new PutObjectCommand({
      Bucket: bucket,
      Key: thumbnailKey,
      Body: thumbnail,
      ContentType: "image/webp",
    })
  );

  console.log(`Miniatura creada: s3://${bucket}/${thumbnailKey}`);
};

Ejemplo 3: Lambda Programada (EventBridge)

# Configuración de EventBridge en template.yaml
SendReminderFunction:
  Type: AWS::Serverless::Function
  Properties:
    Handler: src/functions/sendReminder/index.handler
    Runtime: nodejs20.x
    Timeout: 300
    Environment:
      Variables:
        DATABASE_URL: !Sub "{{resolve:secretsmanager:${AWS::StackName}/database-url}}"
        RESEND_API_KEY: !Sub "{{resolve:secretsmanager:${AWS::StackName}/resend-api-key}}"
    Events:
      DailyReminder:
        Type: Schedule
        Properties:
          Schedule: cron(0 0 * * ? *)  # UTC 0:00 = CDMX 18:00 / Buenos Aires 21:00

Dejar que Claude Code Diseñe las Políticas IAM

claude -p "
Generar una política IAM de mínimo privilegio en JSON para una Lambda que necesita:
- GetObject del bucket S3 my-uploads
- PutItem/UpdateItem en la tabla DynamoDB ProcessingJobs
- SendMessage a la cola SQS ProcessingQueue
- Escribir en CloudWatch Logs

Inferir los ARN específicos a partir de los nombres de recursos proporcionados.
"
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject"],
      "Resource": "arn:aws:s3:::my-uploads/*"
    },
    {
      "Effect": "Allow",
      "Action": ["dynamodb:PutItem", "dynamodb:UpdateItem"],
      "Resource": "arn:aws:dynamodb:us-east-1:*:table/ProcessingJobs"
    },
    {
      "Effect": "Allow",
      "Action": ["sqs:SendMessage"],
      "Resource": "arn:aws:sqs:us-east-1:*:ProcessingQueue"
    },
    {
      "Effect": "Allow",
      "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "arn:aws:logs:*:*:log-group:/aws/lambda/*"
    }
  ]
}

Pruebas Locales y Despliegue en Producción

# Compilar
sam build

# Iniciar API localmente
sam local start-api --port 3001

# Invocación de prueba única
sam local invoke GetUserFunction --event events/get-user.json

# Ejecutar todo con Claude Code
claude -p "
Ejecutar sam build,
verificar resultados con sam local invoke GetUserFunction --event events/test-get-user.json.
Si todo está bien, ejecutar sam deploy --config-env dev.
"

Los 5 Errores Más Comunes

1. Inicialización que ignora los arranques en frío (cold starts)

// ❌ Crear el cliente dentro del handler en cada invocación
export const handler = async () => {
  const ddb = new DynamoDBClient({});  // ← se instancia en cada invocación
};

// ✅ Inicializar una vez en el ámbito del módulo
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient({}));
export const handler = async () => { /* reutilizar ddb */ };

2. Dejar el timeout en el valor predeterminado (3 segundos) Para DynamoDB + APIs externas, establece al menos 10-30 segundos. Siempre configura según los requisitos reales de procesamiento.

3. Escribir secretos directamente en variables de entorno

# ❌ Codificado directamente en la plantilla
Environment:
  Variables:
    DB_PASSWORD: "my-secret"

# ✅ A través de Secrets Manager
Environment:
  Variables:
    DB_PASSWORD: !Sub "{{resolve:secretsmanager:myapp/db-password}}"

4. Retrasos de arranque en frío con Lambda en VPC Colocar una Lambda dentro de una VPC para conectividad con RDS agrega varios segundos al arranque en frío. Solucionar con Provisioned Concurrency o RDS Proxy.

5. Paquetes de despliegue sobredimensionados Empaquetar node_modules junto puede alcanzar el límite de 250 MB. Mover las bibliotecas compartidas a un Lambda Layer.

Resumen

TareaContribución de Claude Code
Implementación del handlerGenerar definiciones de tipo, manejo de errores y lógica de una sola vez
Plantilla SAMSalida automática de eventos, IAM y variables de entorno
Política IAMGenerar con precisión diseños de mínimo privilegio
Pruebas localesAutomatizar la ejecución de sam invoke y la evaluación de resultados
DespliegueEjecutar build + deploy como un flujo de trabajo unificado

Claude Code se encarga de las partes más laboriosas del desarrollo Lambda — definiciones de tipo y escritura de plantillas. Concentrarse en la lógica de negocio puede multiplicar la velocidad de implementación entre 3 y 5 veces.

Artículos Relacionados

Referencias

#claude-code #aws #lambda #serverless #api-gateway #typescript

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.

Gratis

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.

Masa

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.