AWS-Deployment mit Claude Code: CDK, GitHub Actions, IAM, Logs und Rollback
Praxisguide für eine kleine AWS-API mit Claude Code, CDK, OIDC, Least-Privilege-IAM, Logs, Rollback und Kostenlimits.
Der gefährliche Weg mit Claude Code und AWS ist, einfach “baue mir eine AWS-Architektur” zu fragen und die Antwort ungeprüft zu übernehmen. Ein produktionsnahes Deployment besteht nicht nur aus einem Diagramm. Es braucht ausführbaren Infrastrukturcode, begrenzte IAM-Rechte, Secret-Handling, Logs, Rollback und Kostenkontrollen.
Dieser Guide implementiert einen sicheren Startpunkt für eine kleine Web-App oder API: API Gateway + Lambda + AWS CDK + GitHub Actions. CDK steht für Infrastructure as Code, also AWS-Ressourcen als Code statt Klickarbeit in der Konsole. IAM ist das Berechtigungssystem: wer oder was darf welche Aktion ausführen. OIDC erlaubt GitHub Actions, mit temporären Credentials eine AWS-Rolle anzunehmen, ohne langfristige AWS-Schlüssel in GitHub Secrets zu speichern.
Claude Code ist hier nützlich, weil es das Repository lesen, mehrere Dateien ändern, cdk synth und cdk diff ausführen, Fehler erklären und Betriebsabläufe dokumentieren kann. Produktdetails stehen in der Claude Code Dokumentation. Für AWS-Details sollten die offiziellen Quellen maßgeblich sein: AWS CDK NodejsFunction, API Gateway Lambda proxy integration, Lambda environment variables, Lambda CloudWatch Logs und IAM best practices.
AWS-Ziel vor dem Coding festlegen
Wenn das Ziel unscharf bleibt, baut Claude Code schnell zu viel. Benennen Sie zuerst die Workload-Form.
| Option | Geeignet für | Stärke | Risiko |
|---|---|---|---|
| Lambda + API Gateway | Kleine APIs, Kontaktformulare, Webhooks, leichte Admin-Backends | Wenig Serverbetrieb, guter Einstieg bei geringem Traffic | Nicht ideal für lange Jobs, dauerhafte Verbindungen oder große Container |
| ECS/Fargate + ALB | Docker-APIs, Always-on-Services, API plus Worker | Hohe Container-Freiheit, Migration bestehender Apps einfacher | VPC, ALB, Task Definition, Scaling und Images müssen gepflegt werden |
| Amplify oder S3 + CloudFront | Statische Sites, SPAs, frontend-lastige Apps | Schnelle CDN-Auslieferung und einfache Operation | API, Auth und Backend-Jobs brauchen eigenes Design |
Dieser Artikel wählt Lambda + API Gateway, weil das in Beratungsgesprächen häufig passt: eine kleine API sicher auf AWS bringen, ohne sofort eine Plattform zu bauen. Ergänzend sind Claude Code AWS Lambda, Claude Code AWS IAM, Claude Code API Gateway und Claude Code Security Best Practices sinnvoll.
flowchart LR
User[Nutzer] --> Api[API Gateway]
Api --> Fn[Lambda Node.js API]
Fn --> Secret[Secrets Manager]
Fn --> Logs[CloudWatch Logs]
GitHub[GitHub Actions OIDC] --> CDK[AWS CDK deploy]
CDK --> Api
CDK --> Fn
Konkrete Use Cases
Der erste Use Case ist ein Kontakt- oder Lead-Formular. Das Frontend bleibt auf der bestehenden Website, nur der Submit-Endpunkt liegt auf API Gateway + Lambda. Throttling, API Key und CloudWatch Logs helfen bei Spam und Fehleranalyse.
Der zweite Use Case ist eine MVP-API für ein SaaS. Starten Sie mit kleinen Routen wie /v1/health, /v1/contact und /v1/webhook. Schreiben Sie Claude Code ausdrücklich, dass VPC, RDS, Queues und Container erst bei echtem Bedarf entstehen.
Der dritte Use Case sind interne Webhooks: Slack-Alarme, CMS-Callbacks, Freigaben oder leichte Admin-Aktionen. Lambda passt, wenn jede Anfrage schnell beendet ist. Für Retries, lange Verarbeitung oder Fan-out ergänzen Sie bewusst SQS oder Step Functions.
Der vierte Use Case ist die Migration manueller Deployments nach CI/CD. Viele Teams deployen noch vom Laptop oder klicken in der AWS-Konsole. Claude Code kann daraus CDK und GitHub Actions machen; Produktionsfreigabe, Rollback-Regeln und Risikoentscheidung bleiben beim Team.
Deployment-Regeln für Claude Code
Legen Sie im Repository ein CLAUDE.md an. Das ist der Rahmen, damit eine kleine API nicht zu einer teuren Plattform wird.
# AWS deployment rules
- Use AWS CDK v2 and TypeScript.
- Target region: eu-central-1 unless explicitly changed.
- Do not create VPC resources for this small API unless required.
- Prefer API Gateway + Lambda for the first release.
- Runtime secrets must come from AWS Secrets Manager, not plaintext env vars.
- Use IAM grants such as secret.grantRead(handler) instead of wildcard policies.
- Add CloudWatch log retention and reserved concurrency.
- Before deploy, run npm test, npx cdk synth, and npx cdk diff.
- Never paste AWS access keys into files or GitHub Secrets.
Danach formulieren Sie die Aufgabe mit klaren Grenzen:
Füge diesem Repository einen CDK v2 SmallApiStack hinzu.
Erstelle eine API Gateway REST API und eine Node.js 20 Lambda mit /v1/health und /v1/contact.
Lies Runtime-Konfiguration aus Secrets Manager: prod/claude-code-demo/api.
Halte die Lambda Execution Role auf Least Privilege und ergänze Log Retention, reserved concurrency und API Gateway throttling.
Der GitHub Actions Workflow soll nur OIDC verwenden. Keine langfristigen AWS Keys.
Führe nach der Änderung npm test, npx cdk synth und npx cdk diff aus und erkläre das Ergebnis.
CDK-Projekt erstellen
Benötigt werden Node.js, AWS CLI v2, AWS CDK CLI und ein authentifiziertes AWS-Profil. Die Befehle sind Bash; unter Windows am besten WSL oder Git Bash nutzen.
mkdir claude-code-aws-api
cd claude-code-aws-api
npx cdk init app --language typescript
npm install @aws-sdk/client-secrets-manager
npm install --save-dev esbuild @types/aws-lambda
mkdir -p lambda
aws sts get-caller-identity
Erstellen Sie die Runtime-Konfiguration einmalig. Echte API Keys, Datenbankpasswörter und Tokens gehören nicht ins Repository und nicht als Klartext in Lambda-Umgebungsvariablen.
aws secretsmanager create-secret \
--name prod/claude-code-demo/api \
--secret-string '{"supportQueue":"aws-consulting"}' \
--region eu-central-1
Lambda Handler implementieren
Erstellen Sie lambda/handler.ts. Der Code loggt nur operative Metadaten, nicht den vollständigen Request Body und keine Secrets.
import type {
APIGatewayProxyEvent,
APIGatewayProxyResult,
} from "aws-lambda";
import {
GetSecretValueCommand,
SecretsManagerClient,
} from "@aws-sdk/client-secrets-manager";
const secrets = new SecretsManagerClient({});
let cachedConfig: Record<string, string> | undefined;
async function loadConfig(): Promise<Record<string, string>> {
if (cachedConfig) return cachedConfig;
const secretArn = process.env.SECRET_ARN;
if (!secretArn) throw new Error("SECRET_ARN is not configured");
const result = await secrets.send(
new GetSecretValueCommand({ SecretId: secretArn }),
);
cachedConfig = JSON.parse(result.SecretString ?? "{}");
return cachedConfig;
}
function json(statusCode: number, body: unknown): APIGatewayProxyResult {
return {
statusCode,
headers: {
"content-type": "application/json",
"cache-control": "no-store",
},
body: JSON.stringify(body),
};
}
export async function handler(
event: APIGatewayProxyEvent,
): Promise<APIGatewayProxyResult> {
try {
if (event.httpMethod === "GET" && event.path.endsWith("/v1/health")) {
return json(200, {
ok: true,
stage: process.env.STAGE ?? "dev",
});
}
if (event.httpMethod === "POST" && event.path.endsWith("/v1/contact")) {
const body = JSON.parse(event.body ?? "{}") as {
email?: string;
message?: string;
};
if (!body.email || !body.message) {
return json(400, { ok: false, message: "email and message required" });
}
const config = await loadConfig();
const emailDomain = body.email.split("@")[1] ?? "unknown";
console.log(
JSON.stringify({
event: "contact_received",
emailDomain,
messageLength: body.message.length,
}),
);
return json(202, {
ok: true,
routedTo: config.supportQueue ?? "manual",
});
}
return json(404, { ok: false, message: "not found" });
} catch (error) {
console.error("handler_error", error);
return json(500, { ok: false, message: "internal error" });
}
}
CDK Stack implementieren
Ersetzen Sie lib/small-api-stack.ts. Wichtig sind appSecret.grantRead(handler), Log Retention, reserved concurrency, Throttling und dataTraceEnabled: false, damit Request Bodies nicht in Produktionslogs landen.
import * as cdk from "aws-cdk-lib";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import * as logs from "aws-cdk-lib/aws-logs";
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
import { Construct } from "constructs";
import * as path from "path";
export class SmallApiStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const appSecret = secretsmanager.Secret.fromSecretNameV2(
this,
"AppSecret",
"prod/claude-code-demo/api",
);
const handler = new nodejs.NodejsFunction(this, "ApiHandler", {
functionName: "claude-code-small-api-prod",
entry: path.join(__dirname, "../lambda/handler.ts"),
handler: "handler",
runtime: lambda.Runtime.NODEJS_20_X,
architecture: lambda.Architecture.ARM_64,
memorySize: 256,
timeout: cdk.Duration.seconds(10),
logRetention: logs.RetentionDays.ONE_MONTH,
reservedConcurrentExecutions: 20,
environment: {
STAGE: "prod",
SECRET_ARN: appSecret.secretArn,
},
bundling: {
minify: true,
sourceMap: true,
externalModules: ["@aws-sdk/*"],
},
});
appSecret.grantRead(handler);
handler.addToRolePolicy(
new iam.PolicyStatement({
actions: ["cloudwatch:PutMetricData"],
resources: ["*"],
conditions: {
StringEquals: {
"cloudwatch:namespace": "ClaudeCodeLab/SmallApi",
},
},
}),
);
const api = new apigateway.RestApi(this, "SmallApi", {
restApiName: "claude-code-small-api",
cloudWatchRole: true,
deployOptions: {
stageName: "prod",
metricsEnabled: true,
loggingLevel: apigateway.MethodLoggingLevel.INFO,
dataTraceEnabled: false,
throttlingRateLimit: 20,
throttlingBurstLimit: 40,
},
});
const v1 = api.root.addResource("v1");
v1.addResource("health").addMethod(
"GET",
new apigateway.LambdaIntegration(handler),
);
v1.addResource("contact").addMethod(
"POST",
new apigateway.LambdaIntegration(handler),
{ apiKeyRequired: true },
);
const apiKey = api.addApiKey("ClientApiKey", {
apiKeyName: "claude-code-small-api-prod-client",
});
const usagePlan = api.addUsagePlan("BasicUsagePlan", {
throttle: { rateLimit: 10, burstLimit: 20 },
quota: { limit: 1000, period: apigateway.Period.MONTH },
});
usagePlan.addApiKey(apiKey);
usagePlan.addApiStage({ stage: api.deploymentStage });
new cdk.CfnOutput(this, "ApiUrl", { value: api.url });
}
}
Aktualisieren Sie auch die Entry-Datei unter bin/.
#!/usr/bin/env node
import * as cdk from "aws-cdk-lib";
import { SmallApiStack } from "../lib/small-api-stack";
const app = new cdk.App();
new SmallApiStack(app, "SmallApiProdStack", {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION ?? "eu-central-1",
},
});
Diff vor dem Deployment prüfen
CDK bootstrap ist beim ersten Deployment in Account und Region nötig.
export AWS_REGION=eu-central-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
npx cdk bootstrap "aws://${AWS_ACCOUNT_ID}/${AWS_REGION}"
npm test
npx cdk synth
npx cdk diff SmallApiProdStack
npx cdk deploy SmallApiProdStack --require-approval never
Lassen Sie Claude Code den cdk diff erklären, besonders IAM-Änderungen. Wenn eine Berechtigung nicht begründet werden kann, gehört sie nicht ungeprüft in Produktion.
API testen und Logs lesen
Holen Sie die URL aus CloudFormation und testen Sie beide Routen.
API_URL=$(aws cloudformation describe-stacks \
--stack-name SmallApiProdStack \
--query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
--output text)
curl "${API_URL}v1/health"
KEY_ID=$(aws apigateway get-api-keys \
--name-query claude-code-small-api-prod-client \
--query "items[0].id" \
--output text)
API_KEY=$(aws apigateway get-api-key \
--api-key "$KEY_ID" \
--include-value \
--query "value" \
--output text)
curl -X POST "${API_URL}v1/contact" \
-H "content-type: application/json" \
-H "x-api-key: ${API_KEY}" \
-d '{"email":"masa@example.com","message":"AWS deployment consultation"}'
Lambda Logs ansehen:
aws logs tail "/aws/lambda/claude-code-small-api-prod" \
--since 1h \
--follow
CloudWatch Logs können ein paar Minuten verzögert erscheinen. Eine kurze Verzögerung ist noch kein Deployment-Fehler.
GitHub Actions mit OIDC verwenden
Speichern Sie keine AWS Access Keys in GitHub Secrets. Erstellen Sie einen OIDC Provider und eine Deployment Role in AWS, und begrenzen Sie die Trust Policy auf Repository und Branch.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
}
}
}
]
}
.github/workflows/deploy-aws.yml:
name: deploy-aws-cdk
on:
push:
branches: ["main"]
workflow_dispatch:
permissions:
id-token: write
contents: read
concurrency:
group: prod-aws-cdk
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-cdk-deploy-prod
aws-region: eu-central-1
- run: npm ci
- run: npm test
- run: npx cdk synth
- run: npx cdk diff SmallApiProdStack
- run: npx cdk deploy SmallApiProdStack --require-approval never
Die Berechtigungspolicy der Deployment Role hängt von CDK bootstrap, CloudFormation Execution Role und Organisationsregeln ab. Nutzen Sie AdministratorAccess nicht als Produktionsstandard. Praktisch ist: OIDC Trust Conditions eng setzen, Permission Boundaries verwenden, falls vorgeschrieben, und mit IAM Access Analyzer reduzieren.
Kosten-Grenzen einbauen
Auch kleine serverless APIs können durch Schleifen, Spam oder zu viele Logs Kosten erzeugen. Der Stack enthält Throttling, Usage Plan und reserved concurrency. Ergänzen Sie AWS Budgets vor dem Launch.
{
"BudgetName": "small-api-monthly-guardrail",
"BudgetLimit": {
"Amount": "20",
"Unit": "USD"
},
"TimeUnit": "MONTHLY",
"BudgetType": "COST"
}
[
{
"Notification": {
"NotificationType": "ACTUAL",
"ComparisonOperator": "GREATER_THAN",
"Threshold": 80,
"ThresholdType": "PERCENTAGE"
},
"Subscribers": [
{
"SubscriptionType": "EMAIL",
"Address": "owner@example.com"
}
]
}
]
aws budgets create-budget \
--account-id "$AWS_ACCOUNT_ID" \
--budget file://budget.json \
--notifications-with-subscribers file://notifications-with-subscribers.json
Budgets und Benachrichtigungen erscheinen nicht immer sofort. Richten Sie sie vor dem Launch ein.
Rollback und typische Fehler
Für den ersten Lambda + API Gateway Service ist der einfachste Rollback oft: schlechten Commit revertieren und erneut deployen.
git revert <bad-commit-sha>
git push origin main
Danach API, CloudFormation Events und Logs prüfen.
curl "${API_URL}v1/health"
aws cloudformation describe-stack-events \
--stack-name SmallApiProdStack \
--max-items 20
aws logs tail "/aws/lambda/claude-code-small-api-prod" --since 30m
Drei Fehler sind häufig: jemand ändert nach CDK in der AWS-Konsole, Secrets landen in Umgebungsvariablen oder Logs, oder API Gateway schreibt Request Bodies in Produktionslogs. Der Stack nutzt dataTraceEnabled: false, aber Review-Disziplin bleibt nötig.
Pre-Deploy-Review mit Claude Code
Nutzen Sie Claude Code als Reviewer, aber verlangen Sie konkrete Befunde.
Führe ein AWS Pre-Deployment-Review durch.
Prüfe:
- Ob der CDK diff übermäßige IAM Wildcards hinzufügt
- Ob Lambda Secrets nur aus Secrets Manager liest
- Ob API Gateway throttling, usage plan und logging hat
- Ob CloudWatch Logs personenbezogene Daten oder komplette Bodies offenlegen könnten
- Ob Rollback-Schritte dokumentiert sind
- Ob npm test, cdk synth und cdk diff bestanden haben
Gib severity, file, line und fix als Tabelle zurück.
Claude Code ist nicht die finale Produktionsfreigabe. Account-Grenzen, Kostenrisiko und Security-Ausnahmen bleiben menschliche Verantwortung. Es macht die Prüfung aber wiederholbar.
Fazit
Der Wert von Claude Code beim AWS-Deployment liegt nicht nur im schnelleren CDK-Code. Er liegt darin, Architektur, IaC, CI/CD, IAM, Secrets, Logs, Rollback und Kostenkontrollen in einen wiederholbaren Ablauf zu bringen.
Für eine kleine Web-API reicht Lambda + API Gateway + CDK oft aus. Wechseln Sie zu ECS/Fargate, wenn wirklich dauerhaft laufende Container nötig sind. Nutzen Sie S3 + CloudFront oder Amplify, wenn der Workload vor allem aus statischem Frontend besteht. Der erste Schritt sollte klein, prüfbar und reversibel sein.
Wenn Ihr Team Claude Code Regeln, AWS CDK Deployment, GitHub Actions OIDC, Least-Privilege-IAM und Betriebschecks für ein echtes Repository entwerfen möchte, buchen Sie eine Claude Code Consulting Session. Masa kann Repository, AWS-Konto und bisherige Deployment-Fehler prüfen und daraus einen umsetzbaren Plan machen.
In der Praxis lässt sich eine kleine Lead-API wie diese in einem halben bis ganzen Tag deploybar machen, sofern das AWS-Konto bereit ist. Kritisch ist weniger der Lambda-Code, sondern IAM, Secrets, Rollback und Kostentransparenz. Claude Code beschleunigt die Umsetzung; Menschen behalten die Verantwortung für Produktionsrisiko.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Workflow von Obsidian zu CLAUDE.md
Obsidian-Arbeitsnotizen in CLAUDE.md-Betriebsnotizen verwandeln und Kontext nicht ständig neu erklären.
Claude Code Revenue CTA Routing: Artikel zu PDF, Gumroad und Beratung führen
Ein Claude-Code-Ablauf, der Leser nach Absicht zu Gratis-PDF, Gumroad oder Beratung führt.
Claude-Code-Team-Handoff-Regeln: Belege, Berechtigungen, Rollback und Umsatzpfade
Ein praktisches Claude-Code-Handoff für Review-Belege, Berechtigungen, Rollback, Gratis-PDF, Gumroad und Beratung.