Docs
/
AWS Cloud
Chapter 12
12 — ECS & Fargate
What is ECS?
Elastic Container Service — run Docker containers on AWS. Two launch types:
| EC2 Launch Type | Fargate Launch Type | |
|---|---|---|
| You manage | EC2 instances (cluster) | Nothing (serverless) |
| Scaling infra | You scale instances | AWS auto-scales |
| Cost | Cheaper at scale | Pay per vCPU/memory/second |
| Control | Full OS access | No OS access |
| Best for | Cost-sensitive, GPU, large workloads | Simplicity, variable workloads |
Architecture
┌─ ECS Cluster ──────────────────────────────┐
│ │
│ ┌─ Service: api (desired: 3) ──────────┐ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │Task 1│ │Task 2│ │Task 3│ │ │
│ │ │(api) │ │(api) │ │(api) │ │ │
│ │ └──────┘ └──────┘ └──────┘ │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌─ Service: worker (desired: 2) ───────┐ │
│ │ ┌──────┐ ┌──────┐ │ │
│ │ │Task 1│ │Task 2│ │ │
│ │ └──────┘ └──────┘ │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
ALB → Service (api) → Tasks → Containers
| Concept | Description |
|---|---|
| Cluster | Logical grouping of services/tasks |
| Task Definition | Blueprint (like docker-compose for one service) |
| Task | Running instance of a task definition (one or more containers) |
| Service | Maintains desired count of tasks, integrates with ALB |
Task Definition
{
"family": "api",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"executionRoleArn": "arn:aws:iam::123:role/ecsTaskExecutionRole",
"taskRoleArn": "arn:aws:iam::123:role/ecsTaskRole",
"containerDefinitions": [
{
"name": "api",
"image": "123456.dkr.ecr.us-east-1.amazonaws.com/my-app:1.0.0",
"portMappings": [
{ "containerPort": 3000, "protocol": "tcp" }
],
"environment": [
{ "name": "NODE_ENV", "value": "production" }
],
"secrets": [
{
"name": "DATABASE_URL",
"valueFrom": "arn:aws:secretsmanager:us-east-1:123:secret:db-url"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/api",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3
}
}
]
}
Roles
| Role | Purpose |
|---|---|
| Execution Role | ECS agent pulls images (ECR), writes logs (CloudWatch), reads secrets |
| Task Role | Your application accesses AWS services (S3, DynamoDB, SQS) |
Service + ALB
aws ecs create-service \
--cluster my-cluster \
--service-name api \
--task-definition api:1 \
--desired-count 3 \
--launch-type FARGATE \
--network-configuration \
"awsvpcConfiguration={subnets=[subnet-a,subnet-b],securityGroups=[sg-xxx],assignPublicIp=DISABLED}" \
--load-balancers \
"targetGroupArn=arn:aws:...target-group/api,containerName=api,containerPort=3000"
Auto Scaling
# Target tracking: scale based on CPU
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--resource-id service/my-cluster/api \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 2 \
--max-capacity 20
aws application-autoscaling put-scaling-policy \
--policy-name cpu-scaling \
--service-namespace ecs \
--resource-id service/my-cluster/api \
--scalable-dimension ecs:service:DesiredCount \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration \
"TargetValue=70,PredefinedMetricSpecification={PredefinedMetricType=ECSServiceAverageCPUUtilization}"
CI/CD Pipeline
Code push → Build image → Push to ECR → Update ECS service
1. CodeBuild builds Docker image
2. Push to ECR with git SHA tag
3. Update task definition with new image
4. ECS performs rolling update (zero downtime)
ECS vs Lambda vs EKS
| Lambda | ECS Fargate | EKS | |
|---|---|---|---|
| Max runtime | 15 min | Unlimited | Unlimited |
| Container support | No (OCI images) | Yes | Yes |
| Scaling | Instant (ms) | Minutes | Minutes |
| Complexity | Lowest | Medium | Highest |
| Cost (low traffic) | Cheapest | Medium | Expensive |
| Cost (high traffic) | Expensive | Cheaper | Cheapest |
| Use case | Event-driven, APIs | Web apps, microservices | Complex orchestration |
Key Takeaways
- Fargate = serverless containers — no instances to manage
- Task definition = container blueprint; Service = keeps N tasks running
- Use Execution Role for ECS operations, Task Role for app AWS access
- Use Secrets Manager for credentials (not environment variables)
- ALB + ECS Service for load-balanced, auto-scaling web apps
- Choose Lambda for event-driven, ECS for long-running services, EKS for complex K8s workloads