Use Cases (Actualizado: 1/6/2026)

Guía práctica de AWS Lambda con Claude Code: Node.js, IAM y API Gateway

Crea una Lambda Node.js con Claude Code: pruebas locales, IAM de mínimo privilegio, variables, API Gateway y logs.

Guía práctica de AWS Lambda con Claude Code: Node.js, IAM y API Gateway

Claude Code acelera mucho el trabajo con AWS Lambda porque puede preparar en una misma sesión el handler, el evento de prueba, un borrador de IAM, los comandos de despliegue y una checklist de revisión. Esa velocidad es útil, pero los permisos y los costes de AWS son decisiones reales de producción. Usa Claude Code para redactar y revisar; no para conceder permisos, publicar APIs o crear recursos facturables sin revisión humana.

Esta guía muestra un flujo práctico para equipos: crear una Lambda con Node.js, probarla en local, acercar IAM al mínimo privilegio, configurar variables de entorno, conectar API Gateway, leer CloudWatch Logs, actualizar el paquete zip y cerrar el ciclo con una revisión segura. Lambda es un runtime pequeño que se ejecuta cuando llega un evento. IAM es el modelo de permisos que decide qué puede hacer la función. API Gateway es la puerta HTTP que envía peticiones a Lambda.

Conviene tener abiertas las referencias oficiales: introducción a AWS Lambda, Lambda con Node.js, variables de entorno en Lambda, monitorización con CloudWatch Logs y Claude Code common workflows. Los ejemplos usan el runtime Node.js 24 de Lambda, vigente para este artículo el 1 de junio de 2026.

Cuándo usar este patrón

Lambda encaja cuando necesitas una acción pequeña y fiable sin mantener un servidor encendido todo el día. Claude Code aporta más valor cuando genera una estructura repetible y una persona conserva la decisión final.

Caso de usoPor qué encaja LambdaQué puede redactar Claude CodeQué debe revisar una persona
Recepción de webhooksPagos, formularios y SaaS envían eventos brevesValidación de firma, fixtures, respuestas de errorSecretos, reintentos, duplicados
API JSON internaUn endpoint pequeño no necesita servidor permanenteHandler, comandos de API Gateway, formato de logsAutenticación, CORS, exposición, coste
Entrada de batchCSV, imágenes y notificaciones pueden empezar pequeñoValidación, logs estructurados, clases de errorTimeout, estrategia de reintento, borrado seguro

Para una primera prueba, AWS CLI más un paquete zip es rápido. Para operación de equipo, migra después a SAM, CDK u otro flujo IaC revisado.

MétodoMejor paraCuidado con
Consola AWSVer un comportamiento una vezLos pasos manuales no quedan en revisión
AWS CLI + zipPrueba pequeña y reproducibleIAM y variables requieren revisión
SAM / CDKOperación continua en equipoIaC y aprobaciones de despliegue son obligatorias
flowchart LR
  A[Borrador con Claude Code] --> B[Prueba local con Node.js]
  B --> C[Revisión humana de IAM y entorno]
  C --> D[Zip package a dev]
  D --> E[Prueba con API Gateway]
  E --> F[Lectura de CloudWatch Logs]
  F --> A

1. Crear el handler Node.js

Empieza con un index.mjs sin dependencias externas. Acepta eventos HTTP API v2 y también el formato más antiguo de REST API.

// index.mjs
import crypto from "node:crypto";

const allowedStages = new Set(["dev", "staging", "prod"]);

function readConfig() {
  const stage = process.env.APP_STAGE ?? "dev";
  if (!allowedStages.has(stage)) {
    throw new Error(`Invalid APP_STAGE: ${stage}`);
  }

  return {
    stage,
    tableName: process.env.TABLE_NAME ?? "local-orders",
    logLevel: process.env.LOG_LEVEL ?? "info",
  };
}

function log(level, message, details = {}) {
  console.log(
    JSON.stringify({
      level,
      message,
      service: "orders-api",
      ...details,
    })
  );
}

function json(statusCode, body) {
  return {
    statusCode,
    headers: {
      "content-type": "application/json",
    },
    body: JSON.stringify(body),
  };
}

function parseBody(event) {
  if (!event.body) return {};
  const raw = event.isBase64Encoded
    ? Buffer.from(event.body, "base64").toString("utf8")
    : event.body;
  return JSON.parse(raw);
}

export async function handler(event = {}, context = {}) {
  const config = readConfig();
  const method = event.requestContext?.http?.method ?? event.httpMethod ?? "GET";
  const path = event.rawPath ?? event.path ?? "/";
  const requestId = context.awsRequestId ?? "local";

  log("info", "request.start", {
    requestId,
    method,
    path,
    stage: config.stage,
  });

  try {
    if (method === "GET" && path === "/health") {
      return json(200, { ok: true, stage: config.stage });
    }

    if (method === "POST" && path === "/orders") {
      const payload = parseBody(event);
      const orderId = payload.orderId ?? crypto.randomUUID();

      log("info", "order.accepted", {
        requestId,
        orderId,
        tableName: config.tableName,
      });

      return json(202, {
        orderId,
        status: "accepted",
        storedIn: config.tableName,
      });
    }

    return json(404, { error: "not_found", method, path });
  } catch (error) {
    log("error", "request.failed", {
      requestId,
      errorName: error.name,
      errorMessage: error.message,
    });

    return json(500, { error: "internal_error", requestId });
  }
}

Todavía no escribe en DynamoDB. Es intencional: primero confirma recepción del evento, parseo de JSON, forma de la respuesta y logs buscables. La base de datos y sus permisos deben llegar después.

2. Probar en local con un fixture de evento

Un fixture es una entrada fija de prueba. Aunque Claude Code lo genere, guárdalo en el repositorio para que la revisión sea reproducible.

{
  "version": "2.0",
  "routeKey": "POST /orders",
  "rawPath": "/orders",
  "requestContext": {
    "http": {
      "method": "POST",
      "path": "/orders"
    }
  },
  "headers": {
    "content-type": "application/json"
  },
  "body": "{\"orderId\":\"demo-1001\",\"amount\":3200,\"currency\":\"JPY\"}",
  "isBase64Encoded": false
}

Guárdalo como events/create-order.json y añade un runner local.

// local-test.mjs
import { readFile } from "node:fs/promises";
import { handler } from "./index.mjs";

process.env.APP_STAGE = "dev";
process.env.TABLE_NAME = "orders-dev";
process.env.LOG_LEVEL = "debug";

const eventPath = process.argv[2] ?? "events/create-order.json";
const event = JSON.parse(await readFile(eventPath, "utf8"));

const result = await handler(event, { awsRequestId: "local-001" });
console.log(JSON.stringify(result, null, 2));

Ejecuta antes de tocar AWS:

node local-test.mjs events/create-order.json

Si no devuelve statusCode: 202, desplegar solo hará el diagnóstico más lento. Un fixture concreto también permite que Claude Code razone sobre una entrada real, no sobre suposiciones.

3. Mantener IAM cerca del mínimo privilegio

No adjuntes AdministratorAccess al execution role. Empieza con logs y agrega acceso a datos solo cuando el handler lo use.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CreateOwnLogGroupIfMissing",
      "Effect": "Allow",
      "Action": "logs:CreateLogGroup",
      "Resource": "arn:aws:logs:ap-northeast-1:123456789012:*"
    },
    {
      "Sid": "WriteOwnLambdaLogs",
      "Effect": "Allow",
      "Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/lambda/claude-orders-dev:*"
    },
    {
      "Sid": "ReadWriteOnlyOrdersTable",
      "Effect": "Allow",
      "Action": ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem", "dynamodb:Query"],
      "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/orders-dev"
    }
  ]
}

Esto es un borrador, no una respuesta de producción. Cambia cuenta, región, función y tabla; elimina el bloque de DynamoDB hasta que realmente lo uses. Para revisar permisos, consulta también la guía de AWS IAM.

4. Desplegar un paquete zip con AWS CLI

Los siguientes comandos crean recursos reales de AWS y pueden generar coste. Usa una cuenta dev, confirma región y prepara limpieza antes de ejecutar.

export AWS_REGION=ap-northeast-1
export FUNCTION_NAME=claude-orders-dev
export ROLE_NAME=claude-orders-dev-lambda-role
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

zip function.zip index.mjs

Crea trust-policy.json para que Lambda pueda asumir el role.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Guarda el borrador IAM anterior como lambda-policy.json y crea role y función.

aws iam create-role \
  --role-name "$ROLE_NAME" \
  --assume-role-policy-document file://trust-policy.json

aws iam put-role-policy \
  --role-name "$ROLE_NAME" \
  --policy-name claude-orders-dev-inline \
  --policy-document file://lambda-policy.json

ROLE_ARN=$(aws iam get-role \
  --role-name "$ROLE_NAME" \
  --query "Role.Arn" \
  --output text)

aws lambda create-function \
  --function-name "$FUNCTION_NAME" \
  --runtime nodejs24.x \
  --handler index.handler \
  --zip-file fileb://function.zip \
  --role "$ROLE_ARN" \
  --architectures arm64 \
  --timeout 10 \
  --memory-size 128 \
  --environment "Variables={APP_STAGE=dev,TABLE_NAME=orders-dev,LOG_LEVEL=info}" \
  --region "$AWS_REGION"

Para actualizar solo el código:

zip function.zip index.mjs

aws lambda update-function-code \
  --function-name "$FUNCTION_NAME" \
  --zip-file fileb://function.zip \
  --region "$AWS_REGION"

Cuidado con las variables de entorno. Con update-function-configuration, el mapa Variables se reemplaza completo. Lee la configuración actual antes de modificarla. Las claves y contraseñas deberían ir en Secrets Manager o Parameter Store, no como texto plano.

aws lambda update-function-configuration \
  --function-name "$FUNCTION_NAME" \
  --environment "Variables={APP_STAGE=dev,TABLE_NAME=orders-dev,LOG_LEVEL=debug}" \
  --region "$AWS_REGION"

5. Verificar API Gateway y CloudWatch Logs

Primero invoca Lambda directamente.

aws lambda invoke \
  --function-name "$FUNCTION_NAME" \
  --payload fileb://events/create-order.json \
  --region "$AWS_REGION" \
  response.json

cat response.json

Después crea una HTTP API. Esto expone un endpoint público, así que revisa auth, CORS, límites y limpieza antes de ejecutarlo.

API_ID=$(aws apigatewayv2 create-api \
  --name claude-orders-dev-api \
  --protocol-type HTTP \
  --target "arn:aws:lambda:${AWS_REGION}:${ACCOUNT_ID}:function:${FUNCTION_NAME}" \
  --query "ApiId" \
  --output text)

aws lambda add-permission \
  --function-name "$FUNCTION_NAME" \
  --statement-id AllowHttpApiInvoke \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:${AWS_REGION}:${ACCOUNT_ID}:${API_ID}/*/*" \
  --region "$AWS_REGION"

API_ENDPOINT=$(aws apigatewayv2 get-api \
  --api-id "$API_ID" \
  --query "ApiEndpoint" \
  --output text)

curl -s "$API_ENDPOINT/health"
curl -s -X POST "$API_ENDPOINT/orders" \
  -H "content-type: application/json" \
  -d '{"amount":3200,"currency":"JPY"}'

Mira los logs justo después.

aws logs tail "/aws/lambda/${FUNCTION_NAME}" \
  --follow \
  --region "$AWS_REGION"

Si no aparecen logs, revisa región, nombre de función, logs:CreateLogStream y logs:PutLogEvents. Si API Gateway devuelve 500, confirma que la respuesta tenga statusCode, headers y body. Para profundizar, lee la guía de AWS CloudWatch y la guía de AWS API Gateway.

Prompt de Claude para revisar Lambda

Haz que Claude Code explique el riesgo antes de editar o desplegar.

You are reviewing a Node.js AWS Lambda change for a team repository.

Scope:
- Files: index.mjs, events/*.json, IAM policy JSON, deployment commands in docs
- Runtime: nodejs24.x
- Entry point: index.handler

Review for:
1. API Gateway event compatibility and response shape
2. Input validation and JSON parsing failures
3. Environment variables that overwrite existing values
4. IAM actions that are wider than needed
5. CloudWatch logs that expose secrets or personal data
6. AWS resources that can create unexpected cost
7. Local test commands that a reviewer can copy and run

Return:
- blocking issues
- non-blocking improvements
- exact commands to verify locally
- questions a human must answer before deploying

El ciclo seguro es: explorar, planificar, editar, probar localmente, desplegar solo a dev, leer logs y pedir aprobación humana para IAM y costes. Para pasar este proof of concept a CI/CD e IaC, sigue con la guía de deployment en AWS.

Errores frecuentes

El primero es desplegar sin reproducción local. Si el evento tiene una forma incorrecta, un fixture lo descubre antes que CloudWatch.

El segundo es poner secretos directamente en variables de entorno. Son útiles para configuración, pero los secretos necesitan control de acceso y rotación.

El tercero es abrir demasiado IAM. dynamodb:* y Resource: "*" hacen que una demo funcione, pero amplían el impacto de un error.

El cuarto es exponer API Gateway sin responsable claro. Antes de compartir la URL decide autenticación, CORS, throttling, logs y fecha de limpieza.

El quinto es olvidar costes. Lambda parece pequeño, pero API Gateway, CloudWatch Logs, DynamoDB, NAT y llamadas externas también cobran.

ClaudeCodeLab reúne este tipo de flujo en templates y material de formación de Claude Code. Si tu equipo necesita diseñar permisos AWS, CLAUDE.md, prompts de revisión y reglas de aprobación de despliegue sobre un repositorio real, revisa la página de consultoría y formación de Claude Code.

Elimina los recursos de prueba cuando termines.

aws apigatewayv2 delete-api --api-id "$API_ID" --region "$AWS_REGION"
aws lambda delete-function --function-name "$FUNCTION_NAME" --region "$AWS_REGION"
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name claude-orders-dev-inline
aws iam delete-role --role-name "$ROLE_NAME"

Al probar el flujo de este artículo, el mayor beneficio fue que Claude Code mantuvo handler, fixture, borrador IAM y comandos CLI en un mismo contexto revisable. La parte peligrosa no fue generar código, sino decidir permisos y exposición. El patrón fiable es fixture local primero, despliegue dev después, evidencia en CloudWatch y revisión humana de IAM y costes antes de acercarse a producción.

#Claude Code #AWS Lambda #serverless #AWS #Node.js #IAM
Gratis

PDF gratis: cheatsheet de Claude Code

Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.

Cuidamos tus datos y no enviamos spam.

Masa

Sobre el autor

Masa

Ingeniero enfocado en workflows prácticos con Claude Code.