Use Cases (Aktualisiert: 2.6.2026)

Claude Code × AWS ECS/Fargate Komplettanleitung | Sichere Container-Deployments

ECS/Fargate mit Claude Code bereitstellen: Docker, ECR, Task Definitions, Logs, IAM und Praxisfallen.

Claude Code × AWS ECS/Fargate Komplettanleitung | Sichere Container-Deployments

ECS/Fargate ist eine solide Wahl, wenn Container auf AWS laufen sollen, ohne EC2-Instanzen selbst zu verwalten. Schwierig ist aber nicht Docker selbst. Schwierig ist das Zusammenspiel aus ECR, Task Definitions, IAM-Rollen, Secrets Manager, Load Balancing, CloudWatch Logs, Health Checks und Kostenkontrolle.

In diesem Leitfaden ist Claude Code ein Implementierungsassistent, kein ungeprüfter Autopilot. Eine Task Definition ist die Startbeschreibung des Containers, Fargate ist die serverlose Laufzeitumgebung, die ihn ausführt, die execution role erlaubt ECS Image Pull, Secrets und Logs, und die task role nutzt der Anwendungscode für AWS API-Aufrufe.

Bei einer echten Migration von Masa scheiterte der erste Versuch nicht an Docker, sondern am Health Check. Die App brauchte etwa 40 Sekunden zum Starten, ECS prüfte aber zu früh. Claude Code kann die Dateien schnell schreiben, braucht aber klare Betriebsregeln: Startzeit, privates Netzwerk, Logs, Rollback und welche IAM-Berechtigung zu welcher Rolle gehört.

Zielarchitektur

Developer
  |
  | docker build / push
  v
Amazon ECR ----> Amazon ECS Service on AWS Fargate
                       |
                       | pulls secrets / writes logs
                       v
Secrets Manager     CloudWatch Logs
                       ^
                       |
Application Load Balancer -> /health -> Node.js container

Die Beispiele verwenden ap-northeast-1, eine bestehende VPC und eine bestehende ALB target group. Wenn Netzwerk und ALB ebenfalls mit IaC entstehen sollen, passt der interne Claude Code × AWS CloudFormation/CDK Guide dazu. Für Berechtigungen lohnt sich vorher der Claude Code × AWS IAM Guide.

Drei praktische Einsatzfälle

EinsatzfallWarum Fargate passtWorauf achten
SaaS REST APIZwei oder mehr Tasks hinter einem ALB, Rolling Deployments ohne ServerpflegeDB-Verbindungen und Health Checks zuerst planen
Admin BackendKlein starten ohne EC2-Patches oder AMIsdesiredCount 0 macht die erste Anfrage langsam
Gemeinsames API- und Batch-ImageGleiches Image für Service und run-task nutzbarTask role strikt begrenzen

Für kurze, ereignisgesteuerte Workloads ist Claude Code × AWS Lambda oft einfacher. Fargate lohnt sich bei dauerhaftem HTTP, längeren Requests, Docker-Parität oder Runtimes, die nicht gut zu Lambda passen.

1. Minimale API mit Health Check

Beginne mit einer App, die lokal funktioniert. /health wird von ECS und ALB gelesen und sollte leichtgewichtig bleiben. Wenn eine kurzfristig langsame Datenbank sofort 500 auslöst, kann ECS gesunde Tasks ersetzen.

{
  "scripts": {
    "start": "node src/server.js"
  },
  "dependencies": {
    "express": "^4.19.2"
  }
}
// src/server.js
const express = require("express");

const app = express();
const port = Number(process.env.PORT || 3000);

app.get("/health", (_req, res) => {
  res.status(200).json({
    ok: true,
    service: "myapp",
    time: new Date().toISOString(),
  });
});

app.get("/", (_req, res) => {
  res.json({ message: "Hello from ECS Fargate" });
});

app.listen(port, "0.0.0.0", () => {
  console.log(`myapp listening on ${port}`);
});
# Dockerfile
FROM node:22-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev

COPY src ./src
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000

CMD ["node", "src/server.js"]

Prüfe curl -f http://localhost:3000/health, bevor ECS ins Spiel kommt. Im Prompt an Claude Code sollten dieselbe Health-Route für ALB und ECS, 0.0.0.0 als Listen-Adresse und startPeriod für die Startphase stehen.

2. Build und Push nach ECR

Dieses Script erstellt das Repository bei Bedarf, meldet Docker an, baut das Image und pusht einen versionierten Tag. Nur latest zu verwenden erschwert Rollback und Audit.

set -euo pipefail

export AWS_REGION="ap-northeast-1"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export ECR_REPOSITORY="myapp"
export IMAGE_TAG="$(git rev-parse --short HEAD 2>/dev/null || date +%Y%m%d%H%M%S)"
export IMAGE_URI="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}"

aws ecr describe-repositories \
  --repository-names "${ECR_REPOSITORY}" \
  --region "${AWS_REGION}" >/dev/null 2>&1 || \
aws ecr create-repository \
  --repository-name "${ECR_REPOSITORY}" \
  --image-scanning-configuration scanOnPush=true \
  --region "${AWS_REGION}"

aws ecr get-login-password --region "${AWS_REGION}" | \
  docker login --username AWS --password-stdin \
  "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"

docker build -t "${IMAGE_URI}" .
docker push "${IMAGE_URI}"

echo "Pushed ${IMAGE_URI}"

Der offizielle ECR-Ablauf nutzt get-login-password. In CI solltest du GitHub Actions OIDC und kurzlebige AWS Credentials bevorzugen, statt langfristige Access Keys in Repository-Secrets zu speichern.

3. ECS Task Definition registrieren

Fargate Tasks nutzen awsvpc. Wenn Secrets Manager Werte injiziert, braucht die execution role secretsmanager:GetSecretValue; bei einem selbst verwalteten KMS Key zusätzlich kms:Decrypt. Die task role ist für den Anwendungscode da.

set -euo pipefail

export AWS_REGION="ap-northeast-1"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export IMAGE_URI="${IMAGE_URI:?Run the ECR push script first}"
export EXECUTION_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/ecsTaskExecutionRole"
export TASK_ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/myapp-task-role"
export SECRET_ARN="arn:aws:secretsmanager:${AWS_REGION}:${AWS_ACCOUNT_ID}:secret:prod/myapp/DATABASE_URL"

aws logs create-log-group --log-group-name /ecs/myapp --region "${AWS_REGION}" 2>/dev/null || true
aws logs put-retention-policy --log-group-name /ecs/myapp --retention-in-days 30 --region "${AWS_REGION}"

cat > ecs-task-definition.json <<EOF
{
  "family": "myapp-task",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "${EXECUTION_ROLE_ARN}",
  "taskRoleArn": "${TASK_ROLE_ARN}",
  "runtimePlatform": {
    "cpuArchitecture": "X86_64",
    "operatingSystemFamily": "LINUX"
  },
  "containerDefinitions": [
    {
      "name": "app",
      "image": "${IMAGE_URI}",
      "essential": true,
      "portMappings": [
        { "containerPort": 3000, "hostPort": 3000, "protocol": "tcp" }
      ],
      "environment": [
        { "name": "NODE_ENV", "value": "production" },
        { "name": "PORT", "value": "3000" }
      ],
      "secrets": [
        { "name": "DATABASE_URL", "valueFrom": "${SECRET_ARN}" }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/myapp",
          "awslogs-region": "${AWS_REGION}",
          "awslogs-stream-prefix": "ecs"
        }
      },
      "healthCheck": {
        "command": ["CMD-SHELL", "wget -qO- http://localhost:3000/health || exit 1"],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      }
    }
  ]
}
EOF

aws ecs register-task-definition \
  --cli-input-json file://ecs-task-definition.json \
  --region "${AWS_REGION}"

startPeriod verhindert, dass ECS den Container bewertet, bevor die Anwendung realistisch starten konnte.

4. Fargate Service erstellen

Der folgende Befehl nutzt bestehende private Subnets, eine Task Security Group und eine ALB Target Group. Die Task Security Group sollte Port 3000 nur von der ALB Security Group erlauben.

set -euo pipefail

export AWS_REGION="ap-northeast-1"
export CLUSTER_NAME="myapp-cluster"
export SERVICE_NAME="myapp-service"
export TASK_FAMILY="myapp-task"
export SUBNET_1="subnet-xxxxxxxx"
export SUBNET_2="subnet-yyyyyyyy"
export TASK_SECURITY_GROUP="sg-xxxxxxxx"
export TARGET_GROUP_ARN="arn:aws:elasticloadbalancing:ap-northeast-1:123456789012:targetgroup/myapp/abc123"

aws ecs create-cluster \
  --cluster-name "${CLUSTER_NAME}" \
  --region "${AWS_REGION}" >/dev/null

aws ecs create-service \
  --cluster "${CLUSTER_NAME}" \
  --service-name "${SERVICE_NAME}" \
  --task-definition "${TASK_FAMILY}" \
  --desired-count 2 \
  --launch-type FARGATE \
  --platform-version LATEST \
  --health-check-grace-period-seconds 90 \
  --network-configuration "awsvpcConfiguration={subnets=[${SUBNET_1},${SUBNET_2}],securityGroups=[${TASK_SECURITY_GROUP}],assignPublicIp=DISABLED}" \
  --load-balancers "targetGroupArn=${TARGET_GROUP_ARN},containerName=app,containerPort=3000" \
  --region "${AWS_REGION}"

aws ecs wait services-stable \
  --cluster "${CLUSTER_NAME}" \
  --services "${SERVICE_NAME}" \
  --region "${AWS_REGION}"

Bei privaten Subnets mit assignPublicIp=DISABLED braucht die Task trotzdem Zugriff auf ECR, CloudWatch Logs und Secrets Manager. Nutze NAT Gateway oder VPC Endpoints. NAT ist bequem, kann aber in kleinen Testumgebungen der größte Kostenblock sein.

5. CloudWatch Logs und ECS Events prüfen

ECS-Diagnose braucht meist Service Events, Gründe gestoppter Tasks und Anwendungslogs. Gib Claude Code alle drei, wenn es ein fehlgeschlagenes Deployment analysieren soll.

export AWS_REGION="ap-northeast-1"
export CLUSTER_NAME="myapp-cluster"
export SERVICE_NAME="myapp-service"

aws ecs describe-services \
  --cluster "${CLUSTER_NAME}" \
  --services "${SERVICE_NAME}" \
  --query "services[0].events[0:5].[createdAt,message]" \
  --output table \
  --region "${AWS_REGION}"

aws ecs list-tasks \
  --cluster "${CLUSTER_NAME}" \
  --service-name "${SERVICE_NAME}" \
  --desired-status STOPPED \
  --region "${AWS_REGION}"

aws logs tail /ecs/myapp \
  --follow \
  --since 10m \
  --region "${AWS_REGION}"

Häufige Fehler sind blockierter ECR Pull, fehlender Secret-Zugriff, ALB erreicht die Task Security Group nicht, oder die App hört nur auf localhost statt 0.0.0.0.

Implementierungs-Prompt für Claude Code

Erstelle eine AWS ECS/Fargate Deployment-Implementierung für eine Node.js API.

Kontext:
- Region: ap-northeast-1
- ECR repository: myapp
- Container port: 3000
- Health endpoint: /health
- ECS launch type: FARGATE
- Network mode: awsvpc
- Desired count: 2
- Task CPU/memory: 512 / 1024
- Secret: DATABASE_URL aus Secrets Manager injizieren
- Logs: CloudWatch Logs /ecs/myapp, retention 30 days

Lieferumfang:
1. Production Dockerfile
2. Bash Script für Push nach ECR
3. Bash Script zum Registrieren der ECS task definition
4. Bash Script zum Erstellen des Fargate service
5. Bash Script zum Prüfen von CloudWatch Logs
6. Erklärung, die execution role und task role trennt

Einschränkungen:
- Kein Pseudocode. Die Befehle müssen nach Variablenbefüllung mit AWS CLI lauffähig sein.
- Keine Secret-Werte hardcoden.
- Task nicht direkt in einer public subnet veröffentlichen.
- Am Ende offizielle AWS-Dokumentationspunkte nennen, die geprüft werden müssen.

Offizielle AWS-Prüfpunkte

Konkrete Fallen

Die erste Falle ist die Verwechslung von execution role und task role. ECR, Logging und Secret Retrieval gehören in die execution role. DynamoDB, S3, SQS und App-Berechtigungen gehören in die task role.

Die zweite ist ein Secret in der falschen Region. ECS Task, Secrets Manager Secret und KMS Key müssen zusammenpassen. In Multi-Region-Systemen sollte die Secret ARN eine Deployment-Variable pro Umgebung sein.

Die dritte ist Kostenkontrolle. Fargate ist nutzungsbasiert, aber ALB, NAT Gateway, CloudWatch Logs und ECR Storage zählen ebenfalls. Für Tests: Log-Retention setzen, ungenutzte Services stoppen und NAT prüfen.

Die vierte ist ein zu strenger Health Check. Halte /health leicht und verschiebe tiefe Abhängigkeitschecks nach /ready oder in Smoke Tests.

Die fünfte ist Image-Architektur. Wer auf Apple Silicon ARM64 baut und die Task als X86_64 definiert, bekommt Startfehler. Nutze docker buildx build --platform linux/amd64 oder passe runtimePlatform an.

CTA und nächster Schritt

Einzelne Entwickler können diese Scripts in eine kleine API kopieren und mit dem kostenlosen Claude Code Cheatsheet bessere Prompts bauen. Teams, die ECS, IAM, CI/CD, Observability und Rollback gemeinsam gestalten müssen, starten mit Claude Code Training und Beratung. Wiederverwendbare Prompts und Review-Material gibt es bei den ClaudeCodeLab Produkten.

Zusammenfassung

ECS/Fargate ist nicht nur ein Ort für Docker Images. Es ist ein gemeinsames Designproblem aus IAM, Netzwerk, Secrets, Logs, Health Checks und Kosten. Claude Code ist am stärksten, wenn zuerst die Betriebsregeln feststehen und danach lauffähige Dateien entstehen.

Im praktischen Test kam die größte Verbesserung nicht vom Dockerfile, sondern vom Prompt. Die explizite Trennung von execution role und task role, CloudWatch-Log-Befehle und Health Check Grace Period verhinderten Wiederholungsfehler. Der erste Lauf zeigte trotzdem eine fehlende Secret-Berechtigung, aber mit ECS Events und Logs lieferte Claude Code die IAM-Korrektur und Redeploy-Schritte in einem Durchgang.

#claude-code #aws #ecs #fargate #container #devops
Kostenlos

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.

Masa

Über den Autor

Masa

Engineer für praktische Claude-Code-Workflows und Team-Einführung.