Use Cases (Mis à jour: 01/06/2026)

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.

Guide pratique AWS Lambda avec Claude Code : Node.js, IAM et API Gateway

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’usagePourquoi Lambda convientCe que Claude Code peut rédigerCe qu’un humain doit vérifier
Réception de webhooksPaiements, formulaires et SaaS envoient des événements courtsVérification de signature, fixture, réponses d’erreurSecrets, retries, doublons
API JSON interneUne petite API ne nécessite pas de serveur permanentHandler, commandes API Gateway, format des logsAuthentification, CORS, exposition, coût
Entrée de batchCSV, images et notifications peuvent commencer petitValidation d’entrée, logs structurés, erreursTimeout, 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éthodeIdéal pourPoint d’attention
Console AWSVérifier un comportement une seule foisLes étapes manuelles ne restent pas dans l’historique
AWS CLI + zipPreuve de concept petite et reproductibleIAM et variables demandent une vraie revue
SAM / CDKExploitation durable en équipeRevue 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.

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

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.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.