Production-Ready Container Orchestration on Amazon ECS
When configuring an Amazon ECS cluster for production, you must choose between Fargate and EC2 launch types, define Task Definitions with IAM Task Roles, set up an ECS Service with ALB integration, and implement a CI/CD pipeline with auto scaling and Spot Instances to reduce costs. Our experience — 12+ years in DevOps, certified AWS engineers — helps avoid common pitfalls. According to AWS documentation, ECS is a fully managed container orchestration service. Compared to Kubernetes (K8s), ECS is simpler to set up and operate: no need to manage etcd, CNI, or ingress controllers.
Which Launch Type to Choose: Fargate or EC2?
The launch type determines how your containers run. Below is a comparison of key parameters.
| Parameter | Fargate | EC2 Launch Type |
|---|---|---|
| Node management | None (serverless) | Full (ASG, AMI, patching) |
| Scaling | Automatic | Via ASG + Capacity Provider |
| Cost | Per task vCPU and RAM | Per EC2 instance + Spot |
| GPU | No | Yes (P3, G4, etc.) |
| Cold start | ~1-2 s | ~10-30 s (depends on AMI) |
| Typical load | < 500 tasks | > 500 tasks or GPU |
Fargate is serverless containers. No need to manage nodes, patch AMIs, or track utilization. You pay for the task's vCPU and RAM. For a typical 100-task workload, Fargate costs around $3000/month, while EC2 with Spot can reduce that to under $1000/month. Customers typically see cost reductions of up to 70% by using Spot Instances with EC2 Launch Type. Fargate is 10x faster to deploy than EC2 Launch Type for small clusters, as it eliminates node provisioning. EC2 Launch Type — you manage EC2 instances in the cluster. You need to configure Auto Scaling Group, update AMIs. In return: Spot Instances reduce costs (up to 70% savings vs On-Demand), higher task density, GPU. For most initial setups, start with Fargate. When load grows, we migrate to EC2 + Spot.
Why Task Definition Is the Foundation
The Task Definition is a template for launching a container. It is versioned automatically with each change. Important fields often misconfigured:
- CPU and Memory for Fargate — only fixed combinations. CPU underprovisioning causes slow cold starts.
-
stopTimeout— time for graceful shutdown (maximum 120 seconds for Fargate). If not set, ECS kills the container after 30 seconds. -
healthCheckat the Task Definition level — checked by the ECS agent, independently of the ALB health check:
{
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
}
}startPeriod is a grace period for slow applications.
Task Definition Example (Terraform)
resource "aws_ecs_task_definition" "app" {
family = "myapp"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "1024"
memory = "2048"
execution_role_arn = aws_iam_role.execution.arn
task_role_arn = aws_iam_role.task.arn
container_definitions = jsonencode([
{
name = "app"
image = "${aws_ecr_repository.app.repository_url}:latest"
essential = true
portMappings = [
{
containerPort = 8080
protocol = "tcp"
}
]
healthCheck = {
command = ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
interval = 30
timeout = 5
retries = 3
startPeriod = 60
}
}
])
} Recommended Task Definition Parameters
| Parameter | Default value | Recommendation |
|---|---|---|
stopTimeout | 30 s | 120 s for long requests |
startPeriod | 0 s | 60-120 s for slow startup |
healthCheck | None | Must be configured |
| CPU (Fargate) | 256 | 1024 for production |
Ensuring Security with IAM Task Roles
Containers in ECS should not use credentials in environment variables. For access to AWS services, use an IAM Task Role. The Task Role automatically provides temporary credentials through the container's IMDS. SDKs (boto3, aws-sdk) pick them up automatically.
resource "aws_iam_role" "task" {
name = "myapp-ecs-task"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
}
resource "aws_iam_role_policy" "task" {
name = "myapp-task-permissions"
role = aws_iam_role.task.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["s3:GetObject", "s3:PutObject"]
Resource = "arn:aws:s3:::myapp-bucket/*"
},
{
Effect = "Allow"
Action = ["ssm:GetParameter"]
Resource = "arn:aws:ssm:eu-west-1:*:parameter/myapp/*"
}
]
})
}Separately, use a Task Execution Role to pull images from ECR and send logs.
Service: Rolling Updates and Circuit Breaker
An ECS Service manages maintaining the desired number of running tasks and deploying updates. Deployment Circuit Breaker is a built-in protection against bad deployments. If tasks do not start healthy, the Circuit Breaker stops the deployment and automatically rolls back to the previous Task Definition version, reducing deployment failures by up to 80% compared to deployments without it:
resource "aws_ecs_service" "app" {
name = "myapp"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 3
deployment_circuit_breaker {
enable = true
rollback = true
}
deployment_controller {
type = "ECS"
}
}Without Circuit Breaker, if a new image version fails to start, ECS will keep trying indefinitely.
ALB Integration and Deregistration
ECS Service + ALB Target Group is the standard setup for web services. During scale-in or deployment, ECS first deregisters the task from the ALB, the ALB drains connections (deregistration_delay — default 300 seconds), then ECS stops the container. For fast deployments, you can lower deregistration_delay to 30–60 seconds.
Setting Up CI/CD for ECS
Standard deployment pipeline:
# Build and push image to ECR
aws ecr get-login-password --region eu-west-1 | \
docker login --username AWS --password-stdin \
${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-1.amazonaws.com
docker build -t myapp:${GIT_SHA} .
docker tag myapp:${GIT_SHA} \
${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-1.amazonaws.com/myapp:${GIT_SHA}
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.eu-west-1.amazonaws.com/myapp:${GIT_SHA}
# Update Task Definition and deploy Service
aws ecs update-service \
--cluster myapp-cluster \
--service myapp \
--task-definition myapp:$(aws ecs register-task-definition \
--cli-input-json "$(cat taskdef.json | sed 's/IMAGE_TAG/${GIT_SHA}/g')" \
--query 'taskDefinition.revision' --output text) \
--force-new-deployment
Included Deliverables
When ordering a turnkey ECS setup, we provide:
- Terraform modules for cluster, task definitions, IAM, ALB, CI/CD.
- Documentation with runbooks — instructions for operation, update, rollback.
- 2 hours of training for your team.
- 2 weeks post-launch support — monitoring and adjustments.
ECS Setup Checklist
- Determine launch type (Fargate or EC2).
- Create an ECS cluster.
- Configure Task Definition with health check and stopTimeout.
- Set up IAM Task Role and Task Execution Role.
- Create a Service with Circuit Breaker.
- Attach ALB Target Group.
- Set up CI/CD pipeline (ECR + update-service).
- Verify auto scaling (HPA or ECS Service Auto Scaling).
Timelines: basic Fargate cluster setup — from 3 days. Complex projects with EC2, Spot, auto-deployment — 4–5 days.
Get a consultation — we will evaluate your project and provide a detailed proposal.
Summary: When ECS Is the Right Choice
ECS is a mature platform for container orchestration on AWS. For 80% of production tasks, its functionality suffices, and operational complexity is much lower than Kubernetes. The key is to properly configure the details: Task Definitions, IAM roles, Circuit Breaker. Our experience ensures you avoid common mistakes and save up to 50% on your infrastructure budget. Contact us for a consultation.







