Use Cases (Diperbarui: 2/6/2026)

Claude Code × AWS ECS/Fargate Panduan Lengkap | Deployment Container Aman

Deploy ECS/Fargate dengan Claude Code: Docker, ECR, task definition, logs, IAM, dan jebakan nyata.

Claude Code × AWS ECS/Fargate Panduan Lengkap | Deployment Container Aman

ECS/Fargate adalah pilihan kuat untuk menjalankan container di AWS tanpa mengelola instance EC2. Bagian sulitnya bukan Dockerfile. Bagian sulitnya adalah menyambungkan ECR, task definition, IAM role, Secrets Manager, load balancing, CloudWatch Logs, health check, dan kontrol biaya tanpa meninggalkan celah operasional.

Di panduan ini, Claude Code dipakai sebagai asisten implementasi, bukan autopilot tanpa review. Task definition adalah spesifikasi peluncuran container, Fargate adalah runtime serverless yang menjalankannya, execution role mengizinkan ECS menarik image, membaca secret, dan menulis log, sedangkan task role dipakai oleh kode aplikasi saat memanggil API AWS.

Dalam migrasi nyata yang dilakukan Masa, kegagalan pertama bukan Docker, melainkan health check. Aplikasi butuh sekitar 40 detik untuk boot, tetapi ECS mengecek terlalu cepat. Claude Code bisa membuat file dengan cepat, tetapi Anda harus memberi tahu batasan operasional: waktu startup, private network, log, rollback, dan pemisahan IAM.

Arsitektur target

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

Contoh memakai ap-northeast-1, VPC yang sudah ada, dan ALB target group yang sudah ada. Jika ingin membuat network dan ALB dengan IaC, baca juga Claude Code × AWS CloudFormation/CDK. Untuk model permission, mulai dari Claude Code × AWS IAM sebelum menyentuh production.

Tiga use case praktis

Use caseMengapa cocok dengan FargateHal yang perlu dijaga
SaaS REST APIMenjaga dua task atau lebih di belakang ALB dengan rolling deploymentDesain koneksi DB dan health check lebih dulu
Backend adminMulai kecil tanpa patch EC2 atau AMIdesiredCount 0 membuat request pertama lambat
Image bersama untuk API dan batchImage yang sama bisa dipakai service dan run-taskBatasi task role dengan least privilege

Jika workload pendek dan event-driven, Claude Code × AWS Lambda bisa lebih sederhana. Pilih Fargate untuk HTTP yang selalu aktif, request lebih panjang, paritas Docker, atau runtime yang kurang cocok di Lambda.

1. API minimal dengan health check

Mulai dari aplikasi yang berjalan lokal. /health dibaca oleh ECS dan ALB, jadi buat ringan. Jika database sementara lambat lalu /health mengembalikan 500, ECS dapat mengganti task yang sebenarnya sehat.

{
  "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"]

Pastikan curl -f http://localhost:3000/health berhasil sebelum pindah ke ECS. Saat meminta Claude Code, jelaskan bahwa ALB dan ECS memakai health path yang sama, aplikasi listen di 0.0.0.0, dan startup dilindungi dengan startPeriod.

2. Build dan push ke ECR

Script ini membuat repository jika belum ada, login, build image, lalu push tag yang berversi. Jangan bergantung hanya pada latest, karena rollback dan audit akan sulit.

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}"

Alur resmi ECR juga memakai get-login-password. Di CI, lebih aman memakai GitHub Actions OIDC dan kredensial AWS sementara daripada access key panjang yang disimpan sebagai repository secret.

3. Daftarkan ECS task definition

Task Fargate memakai network mode awsvpc. Saat mengambil nilai dari Secrets Manager, execution role perlu secretsmanager:GetSecretValue; jika secret memakai KMS key yang Anda kelola, tambahkan kms:Decrypt. Task role adalah untuk kode aplikasi, bukan untuk image pull atau setup log.

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 terlihat kecil, tetapi mahal saat debugging. Ini mencegah ECS menilai container gagal sebelum aplikasi punya waktu cukup untuk boot.

4. Buat Fargate service

Perintah berikut memakai private subnet, task security group, dan ALB target group yang sudah ada. Task security group sebaiknya hanya menerima port 3000 dari security group ALB.

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}"

Jika private subnet memakai assignPublicIp=DISABLED, task tetap butuh jalur ke ECR, CloudWatch Logs, dan Secrets Manager. Gunakan NAT Gateway atau VPC endpoint. NAT mudah, tetapi bisa menjadi biaya terbesar di environment kecil.

5. Periksa CloudWatch Logs dan event ECS

Troubleshooting ECS biasanya perlu service event, alasan stopped task, dan log aplikasi. Berikan ketiganya ke Claude Code saat meminta diagnosis.

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}"

Failure yang sering muncul: image pull dari ECR terblokir, akses secret ditolak, ALB tidak bisa menjangkau task security group, atau aplikasi listen di localhost bukan 0.0.0.0.

Template permintaan untuk Claude Code

Buat implementasi deployment AWS ECS/Fargate untuk API Node.js.

Konteks:
- 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: inject DATABASE_URL dari Secrets Manager
- Logs: CloudWatch Logs /ecs/myapp, retention 30 days

Deliverables:
1. Dockerfile production
2. Bash script untuk push ke ECR
3. Bash script untuk register ECS task definition
4. Bash script untuk membuat Fargate service
5. Bash script untuk inspect CloudWatch Logs
6. Penjelasan yang memisahkan execution role dan task role

Batasan:
- Tidak boleh pseudocode. Command harus runnable dengan AWS CLI setelah variabel diisi.
- Jangan hardcode secret value.
- Jangan expose task langsung di public subnet.
- Akhiri dengan poin dokumentasi resmi AWS yang perlu diverifikasi.

Poin dokumentasi resmi AWS

Jebakan nyata

Pertama, mencampur execution role dan task role. ECR, logging, dan membaca secret masuk ke execution role. DynamoDB, S3, SQS, dan permission aplikasi masuk ke task role.

Kedua, secret berada di region yang salah. ECS task, Secrets Manager secret, dan KMS key harus selaras. Untuk multi-region, jadikan ARN secret sebagai variabel deployment per environment.

Ketiga, biaya. Fargate berbasis penggunaan, tetapi ALB, NAT Gateway, CloudWatch Logs, dan storage ECR juga dihitung. Untuk test environment, set log retention, stop service yang tidak dipakai, dan review penggunaan NAT.

Keempat, health check terlalu ketat. Buat /health ringan dan pindahkan dependency check yang dalam ke /ready atau smoke test.

Kelima, arsitektur image. Jika Anda build ARM64 di Apple Silicon tetapi task didefinisikan sebagai X86_64, startup akan gagal. Gunakan docker buildx build --platform linux/amd64 atau sesuaikan runtimePlatform.

CTA dan langkah berikutnya

Solo builder bisa menyalin script ini ke API kecil dan memakai cheatsheet Claude Code gratis untuk memperbaiki prompt. Tim yang perlu mendesain ECS, IAM, CI/CD, observability, dan rollback bersama bisa mulai dari training dan konsultasi Claude Code. Untuk prompt dan materi review reusable, lihat produk ClaudeCodeLab.

Ringkasan

ECS/Fargate bukan sekadar tempat mengunggah Docker image. Ini adalah desain gabungan antara IAM, network, secret, log, health check, dan biaya. Claude Code paling berguna ketika aturan operasional diberikan lebih dulu, lalu diminta menghasilkan file yang bisa dijalankan.

Setelah mencoba workflow ini, peningkatan terbesar datang dari prompt, bukan Dockerfile. Meminta Claude Code secara eksplisit memisahkan execution role dan task role, menyertakan command CloudWatch Logs, dan menambahkan health check grace period mencegah failure yang sama berulang. Run pertama tetap menemukan permission secret yang kurang, tetapi setelah ECS events dan logs diberikan kembali ke Claude Code, perbaikan IAM dan langkah redeploy keluar dalam satu putaran.

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

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.