Deploying to ECS Fargate
Deploy containerized apps to AWS ECS Fargate — task definitions, services, load balancers, auto-scaling, and CI/CD deployment.
What you'll learn
- ✓How ECS Fargate runs containers without managing servers
- ✓Task definitions, services, and clusters
- ✓Connecting an Application Load Balancer
- ✓Auto-scaling and deployment strategies
Prerequisites
- •Docker basics (Dockerfile, images)
- •AWS fundamentals (VPC, IAM, ECR)
ECS Fargate runs your Docker containers without managing EC2 instances. You define what to run (task definition), how many to run (service), and Fargate handles the infrastructure.
Architecture
ALB → ECS Service → Tasks (containers on Fargate)
→ ECR (container images)
→ CloudWatch (logs)
Push your image to ECR
# Create repository
aws ecr create-repository --repository-name my-app
# Login to ECR
aws ecr get-login-password | docker login --username AWS --password-stdin \
123456789.dkr.ecr.us-east-1.amazonaws.com
# Build and push
docker build -t my-app .
docker tag my-app:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:latest
Task definition
A task definition is a blueprint for your container. Create task-definition.json:
{
"family": "my-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::123456789:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "app",
"image": "123456789.dkr.ecr.us-east-1.amazonaws.com/my-app:latest",
"portMappings": [
{
"containerPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{"name": "NODE_ENV", "value": "production"}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/my-app",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
]
}
Register it:
aws ecs register-task-definition --cli-input-json file://task-definition.json
Create a cluster and service
# Create cluster
aws ecs create-cluster --cluster-name my-cluster
# Create service
aws ecs create-service \
--cluster my-cluster \
--service-name my-app-service \
--task-definition my-app \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-abc,subnet-def],securityGroups=[sg-123],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:...,containerName=app,containerPort=8080"
Auto-scaling
# Register scalable target
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--resource-id service/my-cluster/my-app-service \
--scalable-dimension ecs:service:DesiredCount \
--min-capacity 2 \
--max-capacity 10
# Target tracking policy — scale based on CPU
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--resource-id service/my-cluster/my-app-service \
--scalable-dimension ecs:service:DesiredCount \
--policy-name cpu-scaling \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
}
}'
Rolling deployments
Update the service to deploy a new image:
# Update task definition with new image tag
# Then update the service
aws ecs update-service \
--cluster my-cluster \
--service my-app-service \
--task-definition my-app:2 \
--deployment-configuration "maximumPercent=200,minimumHealthyPercent=100"
ECS performs a rolling deployment — it starts new tasks before stopping old ones.
Health checks
Configure health checks in the ALB target group:
aws elbv2 modify-target-group \
--target-group-arn arn:aws:elasticloadbalancing:... \
--health-check-path /health \
--health-check-interval-seconds 30 \
--healthy-threshold-count 2 \
--unhealthy-threshold-count 3
Your container needs a /health endpoint:
@app.get("/health")
def health():
return {"status": "healthy"}
Secrets from SSM/Secrets Manager
{
"containerDefinitions": [{
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:123456789:secret:db-password"
},
{
"name": "API_KEY",
"valueFrom": "arn:aws:ssm:us-east-1:123456789:parameter/my-app/api-key"
}
]
}]
}
Summary
ECS Fargate removes server management from container deployments. Define your container in a task definition, run it as a service behind a load balancer, and let auto-scaling handle traffic spikes. Use ECR for image storage, CloudWatch for logs, and Secrets Manager for sensitive configuration.
Related articles
- AWS Building REST APIs with API Gateway
Build serverless REST APIs with AWS API Gateway — resources, methods, Lambda integration, authorization, throttling, and deployment stages.
- AWS AWS Lambda with Python: A Practical Guide
Build serverless functions with AWS Lambda and Python — handlers, events, layers, environment variables, API Gateway integration, and best practices.
- AWS S3 Operations with Boto3
Master S3 operations in Python — upload, download, presigned URLs, multipart uploads, lifecycle policies, and event notifications.
- AWS AWS CodeBuild and CodeDeploy Tutorial: Build and Ship on AWS
Learn how to wire AWS CodeBuild and CodeDeploy together to build artifacts, run tests, and deploy to EC2, ECS, or Lambda with blue/green and canary strategies.