Claude Code × AWS ECS/Fargate Komplettanleitung | Container-Deployments automatisieren
AWS ECS/Fargate-Deployments mit Claude Code automatisieren. Von Task-Definitionen über Service-Konfiguration bis Blue/Green-Deployment und CDK-Infrastruktur — aus Masas Praxiserfahrung.
„Ich möchte Container auf AWS betreiben, aber die ECS-Konfiguration ist viel zu komplex” — das ist die Hürde, auf die viele Entwickler zuerst stoßen. Task-Definitionen, Services, Cluster, Load Balancer, Auto Scaling… die Einstellungen sind so zahlreich, dass man nicht weiß, wo man anfangen soll.
Ich baue beruflich serverlose Container-Umgebungen mit ECS/Fargate, und seit ich Claude Code nutze, um einfach meine Architektur zu beschreiben und damit alles von Task-Definitionen bis CDK-Code generieren zu lassen, sind Deployments wesentlich einfacher geworden. Dieser Artikel erklärt die praktischen Schritte.
ECS/Fargate-Grundlagen in 3 Minuten
Cluster: Die "Box", in der ECS-Container laufen
Task-Definition: Container-Spezifikation (Image, CPU, Memory, Env-Variablen)
Service: Definiert, wie viele Tasks laufen (inkl. Auto Scaling)
Fargate: Serverloser Container-Ausführungsmotor — kein Server-Management nötig
Anders als bei EC2 sind bei Fargate kein Server-Provisioning und kein Patch-Management erforderlich. Man kann sich vollständig auf die Container-Konfiguration konzentrieren.
Schritt 1: Task-Definition automatisch generieren
claude -p "
Generiere eine ECS-Task-Definition als JSON mit folgenden Anforderungen:
- App: Node.js API (Port 3000)
- CPU: 512 (0.5 vCPU)
- Memory: 1024 MB
- Umgebungsvariablen: DATABASE_URL (aus Secrets Manager), NODE_ENV=production
- Logging: CloudWatch Logs (Log-Gruppe /ecs/myapp)
- Health-Check: /health-Endpunkt, 30-Sekunden-Intervall
- Container-Image: 123456789.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
- Execution Role: ecsTaskExecutionRole
- Task Role: myapp-task-role (Zugriff auf DynamoDB und S3)
"
Generierte Task-Definition:
{
"family": "myapp-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::123456789:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123456789:role/myapp-task-role",
"containerDefinitions": [
{
"name": "myapp",
"image": "123456789.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest",
"portMappings": [{ "containerPort": 3000, "protocol": "tcp" }],
"environment": [{ "name": "NODE_ENV", "value": "production" }],
"secrets": [
{
"name": "DATABASE_URL",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789:secret:prod/database-url"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/myapp",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
}
]
}
Schritt 2: ECS/Fargate-Infrastruktur mit CDK aufbauen
Nicht nur die Task-Definition, sondern auch Cluster, Service und ALB werden mit CDK auf einmal generiert.
claude -p "
Implementiere folgende ECS/Fargate-Umgebung in CDK TypeScript in lib/ecs-stack.ts:
- VPC: Vorhandene VPC importieren (vpcId aus Umgebungsvariable)
- ECS-Cluster: Nur Fargate
- Task-Definition: Gleiche Spezifikation wie oben generiert
- ALB: HTTPS (ACM-Zertifikat-ARN aus Umgebungsvariable), HTTP leitet mit 301 um
- Service: Auto Scaling mit mindestens 2, maximal 10 Tasks
- Skalierung bei 70% CPU-Auslastung
- Target-Tracking-Skalierung
- Blue/Green-Deployment-Unterstützung (CodeDeploy-Integration)
- Service-Zustand im CloudWatch-Dashboard anzeigen
"
// lib/ecs-stack.ts
import * as cdk from "aws-cdk-lib";
import * as ec2 from "aws-cdk-lib/aws-ec2";
import * as ecs from "aws-cdk-lib/aws-ecs";
import * as ecsp from "aws-cdk-lib/aws-ecs-patterns";
import * as acm from "aws-cdk-lib/aws-certificatemanager";
export class EcsStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Vorhandene VPC importieren
const vpc = ec2.Vpc.fromLookup(this, "Vpc", {
vpcId: process.env.VPC_ID!,
});
// ECS-Cluster
const cluster = new ecs.Cluster(this, "Cluster", {
vpc,
clusterName: "myapp-cluster",
containerInsights: true, // CloudWatch Container Insights aktivieren
});
// ACM-Zertifikat
const certificate = acm.Certificate.fromCertificateArn(
this, "Certificate",
process.env.CERTIFICATE_ARN!
);
// Task-Definition
const taskDef = new ecs.FargateTaskDefinition(this, "TaskDef", {
cpu: 512,
memoryLimitMiB: 1024,
});
const container = taskDef.addContainer("app", {
image: ecs.ContainerImage.fromEcrRepository(
ecr.Repository.fromRepositoryName(this, "Repo", "myapp")
),
environment: { NODE_ENV: "production" },
logging: ecs.LogDrivers.awsLogs({ streamPrefix: "ecs" }),
healthCheck: {
command: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
interval: cdk.Duration.seconds(30),
timeout: cdk.Duration.seconds(5),
retries: 3,
startPeriod: cdk.Duration.seconds(60),
},
});
container.addPortMappings({ containerPort: 3000 });
// ALB + Fargate-Service (kompakt mit Patterns)
const service = new ecsp.ApplicationLoadBalancedFargateService(
this, "Service", {
cluster,
taskDefinition: taskDef,
desiredCount: 2,
certificate,
redirectHTTP: true,
publicLoadBalancer: true,
}
);
// Auto-Scaling-Konfiguration
const scaling = service.service.autoScaleTaskCount({
minCapacity: 2,
maxCapacity: 10,
});
scaling.scaleOnCpuUtilization("CpuScaling", {
targetUtilizationPercent: 70,
scaleInCooldown: cdk.Duration.seconds(60),
scaleOutCooldown: cdk.Duration.seconds(60),
});
// Output
new cdk.CfnOutput(this, "LoadBalancerDns", {
value: service.loadBalancer.loadBalancerDnsName,
});
}
}
Schritt 3: CI/CD-Pipeline mit GitHub Actions aufbauen
claude -p "
Erstelle folgende CI/CD-Pipeline mit GitHub Actions:
1. Trigger bei Push auf den main-Branch
2. Docker-Image bauen und nach ECR pushen
3. Image-Tag in der ECS-Task-Definition auf den neuen SHA aktualisieren
4. Neue Task-Definition im ECS-Service deployen
5. Slack bei erfolgreichem Deployment benachrichtigen
Umgebung: ap-northeast-1, ECR-Repository-Name: myapp
"
name: Deploy to ECS
on:
push:
branches: [main]
env:
AWS_REGION: ap-northeast-1
ECR_REPOSITORY: myapp
ECS_CLUSTER: myapp-cluster
ECS_SERVICE: myapp-service
CONTAINER_NAME: app
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push image to ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
- name: Download task definition
run: |
aws ecs describe-task-definition --task-definition myapp-task \
--query taskDefinition > task-definition.json
- name: Update ECS task definition with new image
id: task-def
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: task-definition.json
container-name: ${{ env.CONTAINER_NAME }}
image: ${{ steps.build-image.outputs.image }}
- name: Deploy to ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
service: ${{ env.ECS_SERVICE }}
cluster: ${{ env.ECS_CLUSTER }}
wait-for-service-stability: true
- name: Notify Slack on success
if: success()
uses: slackapi/slack-github-action@v1
with:
webhook: ${{ secrets.SLACK_WEBHOOK }}
payload: |
{"text": "✅ Deployed to ECS: ${{ github.sha }}"}
Schritt 4: Blue/Green-Deployment konfigurieren
claude -p "
Generiere CDK-Code und eine AppSpec-Datei für das Einrichten von Blue/Green-Deployment (CodeDeploy) für einen ECS-Service.
Rollback-Bedingung: Automatischer Rollback, wenn innerhalb von 5 Minuten nach dem Deployment ein CloudWatch-Alarm ausgelöst wird.
"
# appspec.yaml (für CodeDeploy)
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION>
LoadBalancerInfo:
ContainerName: app
ContainerPort: 3000
PlatformVersion: LATEST
Hooks:
- BeforeAllowTraffic: "arn:aws:lambda:ap-northeast-1:123456789:function:health-check"
- AfterAllowTraffic: "arn:aws:lambda:ap-northeast-1:123456789:function:smoke-test"
Die 5 häufigsten Fallstricke
1. startPeriod im Health-Check vergessen
Fargate-Container führen sofort beim Start Health-Checks durch. Wenn die Anwendung langsam startet, wird sie sofort als UNHEALTHY markiert. Setzen Sie startPeriod: 60 (Sekunden), um der App Zeit zum Starten zu geben.
2. Task-Role und Execution-Role verwechseln
executionRole (ecsTaskExecutionRole): Berechtigungen zum Starten des Containers
→ Image aus ECR pullen, in CloudWatch Logs schreiben
taskRole (myapp-task-role): Berechtigungen, die die Anwendung nutzt
→ Zugriff auf DynamoDB, S3, SQS usw.
Es passiert sehr leicht, Berechtigungen der falschen Role zuzuordnen.
3. Security-Group-Konfiguration im awsvpc-Netzwerkmodus
Fargate erfordert zwingend den awsvpc-Netzwerkmodus. Wenn man vergisst, die Security Group des Containers so einzuschränken, dass nur Datenverkehr vom ALB erlaubt ist, wird der Container direkt dem Internet ausgesetzt.
4. Execution-Role für Secrets Manager erforderlich
Um Werte aus dem Secrets Manager über secrets abzurufen, muss die executionRole die Berechtigung secretsmanager:GetSecretValue haben. Das Fehlen dieser Berechtigung ist ein häufiger Grund, warum Container nicht starten.
5. Das desired_count: 0-Problem bei Deployments
Ein Service mit Auto-Scaling-Minimum 0 kann nachts alle Container herunterfahren, was am Morgen zu langsamen Starts führt. Setzen Sie das Minimum in der Produktion auf mindestens 2.
Zusammenfassung
| Aufgabe | Claude Codes Beitrag |
|---|---|
| Task-Definition generieren | Vollständiges JSON aus Anforderungen |
| CDK-Implementierung | Cluster, Service, ALB, Auto Scaling gemeinsam generiert |
| CI/CD-Setup | GitHub-Actions-Workflow-Generierung |
| Blue/Green-Deployment | AppSpec und CodeDeploy-Config automatisch generiert |
| Fehlerbehebung | Ursache und Lösung aus Fehler-Logs ermittelt |
ECS hat viele Konfigurationspunkte, aber indem man Claude Code sagt „Ich möchte diese Art von Setup”, erhält man eine vollständige, Best-Practice-konforme Konfiguration. Mit CDK anzufangen ist der einfachste und empfohlene Ansatz.
Verwandte Artikel
- Claude Code × AWS Lambda Komplettanleitung
- Claude Code × AWS IAM Komplettanleitung
- Claude Code × AWS CloudFormation/CDK Komplettanleitung
Referenzen
Bring deinen Claude-Code-Workflow aufs nächste Level
50 in der Praxis erprobte Prompt-Vorlagen zum direkten Copy-and-paste in Claude Code.
Kostenloses PDF: Claude-Code-Spickzettel in 5 Minuten
Trag einfach deine E-Mail-Adresse ein – wir senden dir den A4-Spickzettel als PDF sofort zu.
Wir behandeln deine Daten sorgfältig und senden niemals Spam.
Über den Autor
Masa
Ingenieur, der Claude Code intensiv nutzt. Betreibt claudecode-lab.com, ein Tech-Medium in 10 Sprachen mit über 2.000 Seiten.
Ähnliche Artikel
Claude Code × Amazon Bedrock Komplettleitfaden | Claude produktiv auf AWS betreiben
Komplettleitfaden zur Nutzung von Amazon Bedrock mit Claude Code. Von IAM-Authentifizierung, Streaming, Lambda-Integration und RAG-Implementierung bis zur Kostenoptimierung – basierend auf Masas Produktionserfahrung.
Claude Code × AWS CodePipeline/CodeBuild Komplettanleitung | CI/CD-Pipeline automatisch aufbauen
CI/CD mit AWS CodePipeline & CodeBuild automatisch aufbauen mit Claude Code. Praxisbeispiele für Pipeline-Design, buildspec.yml-Generierung, Testautomatisierung und CDK-Infrastruktur.
Claude Code × AWS CloudWatch Komplettanleitung | Log-Analyse, Alarme & Dashboard-Automatisierung
AWS CloudWatch mit Claude Code effizienter nutzen. Praxisnaher Code für Log-Musteranalyse, automatische Alarmkonfiguration, Metriken-Dashboards und Incident-Untersuchung.