Guide pratique AWS Lambda avec Claude Code : Node.js, IAM et API Gateway
Créez une Lambda Node.js avec Claude Code : tests locaux, IAM minimal, variables, API Gateway et logs CloudWatch.
Claude Code est très utile avec AWS Lambda, car il peut préparer dans le même contexte le handler, un événement de test, un brouillon de policy IAM, les commandes de déploiement et une checklist de revue. Cette vitesse aide beaucoup, mais les permissions et les coûts AWS restent des décisions de production. Utilisez Claude Code pour rédiger et vérifier, pas pour accorder aveuglément des droits IAM, publier une API ou créer des ressources facturables sans validation humaine.
Ce guide décrit un flux réaliste pour une équipe : créer une Lambda Node.js, la tester localement, limiter IAM au plus près du minimum nécessaire, configurer les variables d’environnement, connecter API Gateway, lire CloudWatch Logs, mettre à jour le package zip et organiser une boucle de revue sûre. Lambda est un petit runtime qui démarre quand un événement arrive. IAM définit ce que la fonction a le droit de faire. API Gateway est l’entrée HTTP qui transmet les requêtes à Lambda.
Gardez les références officielles sous la main : démarrer avec AWS Lambda, Lambda avec Node.js, variables d’environnement Lambda, surveillance avec CloudWatch Logs et Claude Code common workflows. Les exemples utilisent le runtime Lambda Node.js 24, à jour pour cet article au 1er juin 2026.
Quand utiliser ce modèle
Lambda convient aux traitements courts et fiables qui ne justifient pas un serveur permanent. Claude Code est le plus efficace quand il produit une structure répétable et qu’un reviewer garde la décision finale.
| Cas d’usage | Pourquoi Lambda convient | Ce que Claude Code peut rédiger | Ce qu’un humain doit vérifier |
|---|---|---|---|
| Réception de webhooks | Paiements, formulaires et SaaS envoient des événements courts | Vérification de signature, fixture, réponses d’erreur | Secrets, retries, doublons |
| API JSON interne | Une petite API ne nécessite pas de serveur permanent | Handler, commandes API Gateway, format des logs | Authentification, CORS, exposition, coût |
| Entrée de batch | CSV, images et notifications peuvent commencer petit | Validation d’entrée, logs structurés, erreurs | Timeout, stratégie de retry, suppression sûre |
Pour une première preuve de concept, AWS CLI avec un package zip est rapide. Pour une exploitation d’équipe, déplacez ensuite le même fonctionnement vers SAM, CDK ou un autre flux IaC revu.
| Méthode | Idéal pour | Point d’attention |
|---|---|---|
| Console AWS | Vérifier un comportement une seule fois | Les étapes manuelles ne restent pas dans l’historique |
| AWS CLI + zip | Preuve de concept petite et reproductible | IAM et variables demandent une vraie revue |
| SAM / CDK | Exploitation durable en équipe | Revue IaC et approbation de déploiement obligatoires |
flowchart LR
A[Brouillon avec Claude Code] --> B[Test Node.js local]
B --> C[Revue humaine IAM et environnement]
C --> D[Package zip vers dev]
D --> E[Test via API Gateway]
E --> F[Lecture CloudWatch Logs]
F --> A
1. Créer le handler Node.js
Commencez par un index.mjs sans dépendance externe. Il accepte les événements HTTP API v2 et l’ancien format 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 });
}
}
Cette première version n’écrit pas encore dans DynamoDB. C’est volontaire. Pour débuter, il faut d’abord valider la réception de l’événement, le parsing JSON, la forme de réponse et les logs recherchables.
2. Tester localement avec une fixture d’événement
Une fixture est une entrée de test fixe. Même si Claude Code la génère, gardez-la dans le dépôt pour rendre la revue reproductible.
{
"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
}
Enregistrez-la dans events/create-order.json, puis ajoutez 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));
Exécutez avant de toucher AWS :
node local-test.mjs events/create-order.json
Si le résultat local ne renvoie pas statusCode: 202, le déploiement ne fera que ralentir le diagnostic. Une fixture concrète aide aussi Claude Code à raisonner sur une entrée réelle.
3. Garder IAM proche du moindre privilège
N’attachez pas AdministratorAccess au rôle d’exécution Lambda. Commencez par les logs, puis ajoutez l’accès aux données seulement quand le handler en a besoin.
{
"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"
}
]
}
Traitez ce JSON comme un brouillon. Remplacez le compte, la région, le nom de fonction et le nom de table. Supprimez le bloc DynamoDB tant qu’il n’est pas utilisé. Pour approfondir, consultez aussi le guide AWS IAM.
4. Déployer un package zip avec AWS CLI
Les commandes suivantes créent de vraies ressources AWS et peuvent générer des coûts. Utilisez un compte dev, confirmez la région et préparez la suppression avant d’exécuter.
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
Créez trust-policy.json pour permettre à Lambda d’assumer le rôle.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Enregistrez le brouillon IAM précédent dans lambda-policy.json, puis créez le rôle et la fonction.
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"
Pour mettre à jour uniquement le code :
zip function.zip index.mjs
aws lambda update-function-code \
--function-name "$FUNCTION_NAME" \
--zip-file fileb://function.zip \
--region "$AWS_REGION"
Attention aux variables d’environnement. Avec update-function-configuration, la map Variables est remplacée entièrement. Lisez la configuration actuelle avant de la modifier. Les mots de passe et clés API doivent plutôt aller dans Secrets Manager ou Parameter Store.
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. Vérifier API Gateway et CloudWatch Logs
Invoquez d’abord Lambda directement.
aws lambda invoke \
--function-name "$FUNCTION_NAME" \
--payload fileb://events/create-order.json \
--region "$AWS_REGION" \
response.json
cat response.json
Créez ensuite une HTTP API. Cela expose un endpoint public : vérifiez l’authentification, CORS, les limites et le plan de suppression avant de lancer la commande.
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"}'
Lisez les logs juste après le test.
aws logs tail "/aws/lambda/${FUNCTION_NAME}" \
--follow \
--region "$AWS_REGION"
S’il n’y a pas de logs, vérifiez la région, le nom de fonction, logs:CreateLogStream et logs:PutLogEvents. Si API Gateway renvoie 500, confirmez que la réponse Lambda contient statusCode, headers et body. Pour aller plus loin, lisez le guide AWS CloudWatch et le guide AWS API Gateway.
Prompt Claude pour revoir une Lambda
Demandez à Claude Code d’expliquer les risques avant toute modification ou déploiement.
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
La boucle sûre est : explorer, planifier, éditer, tester localement, déployer seulement en dev, lire les logs, puis faire approuver IAM et les coûts par un humain. Pour transformer cette preuve de concept en CI/CD ou IaC, continuez avec le guide de déploiement AWS.
Pièges fréquents
Le premier piège est de déployer sans reproduction locale. Si la forme de l’événement est incorrecte, une fixture le montre plus vite que CloudWatch.
Le deuxième est de mettre des secrets directement dans les variables d’environnement. Elles sont pratiques pour la configuration, mais les secrets nécessitent contrôle d’accès et rotation.
Le troisième est d’élargir IAM. dynamodb:* et Resource: "*" font passer les démos, mais augmentent l’impact d’une erreur.
Le quatrième est d’exposer un endpoint API Gateway sans responsable clair. Décidez authentification, CORS, throttling, logs et date de nettoyage avant de partager l’URL.
Le cinquième est d’oublier les coûts. Lambda paraît petit, mais API Gateway, CloudWatch Logs, DynamoDB, NAT et les appels externes peuvent tous facturer.
ClaudeCodeLab regroupe ce type de flux dans des templates et supports de formation Claude Code. Si votre équipe veut concevoir les permissions AWS, CLAUDE.md, les prompts de revue et les règles d’approbation de déploiement sur un vrai dépôt, consultez la page consultation et formation Claude Code.
Supprimez les ressources de test quand vous avez terminé.
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"
Après avoir réellement suivi le flux de cet article, le gain le plus net est que Claude Code garde le handler, la fixture, le brouillon IAM et les commandes CLI dans un même contexte vérifiable. Le risque ne vient pas surtout de la génération de code, mais des décisions de permissions et d’exposition. Le modèle fiable est donc : fixture locale, déploiement dev, preuves CloudWatch, puis revue humaine d’IAM et des coûts avant toute production.
PDF gratuit: cheatsheet Claude Code
Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.
Nous protégeons vos données et n'envoyons pas de spam.
À propos de l'auteur
Masa
Ingénieur spécialisé dans les workflows pratiques avec Claude Code.
Articles liés
Workflow Obsidian vers CLAUDE.md avec Claude Code
Transformer des notes Obsidian en notes CLAUDE.md concises pour reprendre les sessions sans réexpliquer.
Claude Code Revenue CTA Routing : relier articles, PDF, Gumroad et consultation
Un workflow Claude Code pour orienter les lecteurs vers PDF gratuit, Gumroad ou consultation selon l'intention.
Règles de handoff Claude Code en équipe: preuves, permissions, rollback et revenus
Un format concret pour transmettre un travail Claude Code avec preuves, permissions, rollback, PDF gratuit, Gumroad et consultation.