If you've been managing EC2 instances to run Docker containers, you know the overhead: patching the OS, scaling the fleet, monitoring host health. Containers with ECS Fargate strips that away. AWS manages the infrastructure, you define what runs, and you pay only for the resources your tasks consume. It's the container orchestration sweet spot for teams that want simplicity without sacrificing control.
Why Fargate Matters in Your AWS Journey
By Day 20 of building on AWS, you've likely realized that running containers at scale requires more than just Docker. You need orchestration—deciding where tasks run, how many replicas stay healthy, how to roll out new versions. Fargate removes the server management layer entirely. No EC2 instances to patch, no capacity planning headaches, no cluster autoscaling policies to tune. You describe your workload in a task definition, create a service to keep it running, and Fargate handles placement and infrastructure.
This matters because it lets you focus on application concerns. Your team ships features faster when nobody's oncall for host failures or kernel security updates.
Task Definitions — The Blueprint for Your Containers
A task definition is your container's specification. It's where you declare the Docker image, CPU, memory, port mappings, environment variables, secrets, logging, and volumes. Think of it as a declarative contract between your application and Fargate.
Let's say you're running a Node.js API that needs 0.5 vCPU, 1 GB of RAM, listens on port 3000, and requires a database URL secret. Here's how you'd define that in a CloudFormation template:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
MyTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
MyTaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: '512'
Memory: '1024'
ExecutionRoleArn: !GetAtt MyTaskExecutionRole.Arn
ContainerDefinitions:
- Name: api-container
Image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/my-api:latest
Essential: true
PortMappings:
- ContainerPort: 3000
Protocol: tcp
Environment:
- Name: NODE_ENV
Value: production
Secrets:
- Name: DATABASE_URL
ValueFrom: arn:aws:secretsmanager:us-east-1:123456789012:secret:db-url
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: /ecs/my-api
awslogs-region: us-east-1
awslogs-stream-prefix: ecsKey points here: the ExecutionRoleArn grants Fargate permission to pull your image from ECR and fetch secrets from Secrets Manager. The Secrets section references a secret by ARN—Fargate injects it as an environment variable at runtime, keeping it out of logs and environment inspection. NetworkMode: awsvpc is required for Fargate; it means each task gets its own ENI (Elastic Network Interface) and can be placed in a VPC subnet.
CPU and memory come in predefined combinations. Common ones: 256 CPU with 512–2048 MB RAM, 512 CPU with 1–4 GB RAM, 1024 CPU with 2–8 GB RAM, up to 4096 CPU with 30 GB RAM. Choose based on your workload profile—overprovisioning wastes money, underprovisioning causes throttling and failed deployments.
Services — Keeping Your Workload Healthy and Available
A task definition describes one container; a service keeps multiple copies running and healthy. Services handle desired count, load balancing, and replacement of failed tasks. They're what you use to run stateless APIs, workers, and long-lived services in production.
Imagine you want 3 replicas of your API behind a Network Load Balancer, with health checks every 30 seconds. Here's a service definition:
MyService:
Type: AWS::ECS::Service
DependsOn: ALBListenerRule
Properties:
ServiceName: my-api-service
Cluster: !Ref MyCluster
TaskDefinition: !Ref MyTaskDefinition
DesiredCount: 3
LaunchType: FARGATE
LoadBalancers:
- ContainerName: api-container
ContainerPort: 3000
TargetGroupArn: !Ref TargetGroup
NetworkConfiguration:
AwsvpcConfiguration:
AssignPublicIp: DISABLED
Subnets:
- subnet-12345678
- subnet-87654321
SecurityGroups:
- sg-api-group
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentCircuitBreaker:
Enable: true
Rollback: trueThe DesiredCount: 3 means Fargate will run exactly 3 tasks. If one fails, Fargate replaces it. MaximumPercent: 200 allows up to 6 tasks during deployment (100% old + 100% new); MinimumHealthyPercent: 100 ensures at least 3 tasks are always serving traffic. DeploymentCircuitBreaker with rollback enabled will automatically roll back the deployment if too many tasks fail during the update—critical for preventing cascading failures in production.
The AwsvpcConfiguration places tasks in specific subnets with specific security groups. This gives you network isolation and fine-grained access control. A common pattern: run Fargate tasks in private subnets (no direct internet), use a NAT gateway for outbound traffic, and route inbound traffic through an Application or Network Load Balancer in public subnets.
Fargate — The Serverless Container Runtime
Fargate is the compute engine that runs your tasks. Unlike EC2 launch types, where you provision and manage instances, Fargate is fully managed. AWS handles the underlying hosts, patching, scaling the infrastructure, and isolating your workloads. You pay for vCPU and RAM by the second, rounded to the nearest hour.
Pricing is straightforward: if you run a 0.5 vCPU, 1 GB task for an hour, you pay for 0.5 vCPU-hours and 1 GB-hours at published rates (typically $0.04672 per vCPU-hour and $0.00520 per GB-hour in us-east-1). Run 3 replicas around the clock, and that's real cost discipline—you're not paying for idle capacity on underutilized instances.
Trade-offs: Fargate doesn't support GPUs (yet), custom kernel modules, or privileged containers. If you need those, EC2 launch type is your fallback. But for typical stateless workloads—APIs, web apps, workers, microservices—Fargate is simpler and often cheaper than managing EC2 fleets.
One practical tip: Fargate Spot saves up to 70% on compute costs for fault-tolerant, stateless workloads. If your service can tolerate occasional interruptions and you've got enough replicas to absorb the loss, mixing Spot and on-demand capacity is a smart cost move. Use CapacityProviderStrategy in your service to split traffic between providers.
Deployments — Rolling Updates with Safety Nets
Deployments are where your changes reach production. ECS services support rolling updates—gradually replacing old tasks with new ones while keeping your service available. The deployment circuit breaker is your safety net: if too many new tasks fail to reach a healthy state, the entire deployment rolls back automatically.
Here's a real scenario: you push a new image, update the task definition, and trigger a new service deployment. With MaximumPercent: 200 and MinimumHealthyPercent: 100, ECS starts 3 new tasks while keeping the 3 old ones running. Load balancer health checks monitor all 6. If the 3 new tasks pass health checks, ECS drains connections from the old ones and terminates them. If health checks fail on the new tasks, the circuit breaker detects it and rolls back, terminating the new tasks and keeping the old ones running.
aws ecs update-service \
--cluster my-cluster \
--service my-api-service \
--task-definition my-task-definition:2 \
--force-new-deploymentThis CLI command updates the service to use the new task definition and forces a fresh deployment. ECS will orchestrate the rolling update according to your deployment configuration and circuit breaker settings.
Key deployment considerations: health check grace periods let your container finish initialization before the load balancer marks it healthy. Set healthCheckGracePeriodSeconds high enough for your app to boot (e.g., 60 for Node.js, 120 for .NET). Deployment timeout is typically 15 minutes; if a deployment isn't done by then, it fails. For large fleets, bump MinimumHealthyPercent lower (e.g., 50%) to deploy faster; for critical services, keep it high (100%) to maintain capacity.
Common Mistakes
- Forgetting the task execution role. Your tasks won't start if the execution role lacks permissions to pull images or fetch secrets. Always include
AmazonECSTaskExecutionRolePolicyand add custom permissions for ECR, Secrets Manager, and CloudWatch Logs. - Oversizing task resources. Choosing 2 vCPU and 8 GB RAM "just in case" inflates costs and wastes capacity. Profile your app under load, then pick the smallest resource combination that keeps latency acceptable.
- Skipping health checks. Without proper ALB health checks, ECS can't detect unhealthy tasks. Define meaningful health check endpoints and tune thresholds (healthy threshold, unhealthy threshold, interval) for your app's startup time.
- Disabling circuit breaker. Rolling out a broken image without circuit breaker means your entire service goes down as tasks keep failing. Always enable it and test rollback behavior in staging.
- Using public subnets for Fargate tasks. It's tempting for simplicity, but production tasks should run in private subnets for isolation. Route inbound traffic through a load balancer in public subnets.
Key Takeaways
- Task definitions are declarative specifications: image, CPU, memory, ports, environment, secrets, logging. They're versioned and immutable.
- Services keep your desired number of tasks running, provide load balancing, and orchestrate healthy replacement of failed tasks.
- Fargate is fully managed infrastructure. You pay only for resources your tasks use, no EC2 instances to patch or scale.
- Deployment circuit breakers roll back broken releases automatically, protecting production from cascading failures.
- Always enable circuit breaker, set appropriate health check grace periods, right-size resources, and run tasks in private subnets behind load balancers.
- For stateless, fault-tolerant workloads, Fargate Spot can cut costs by 70% compared to on-demand capacity.
Next Steps
Tomorrow (Day 21) we'll dive into ECR—Elastic Container Registry—where you build and store your images, and how to set up secure, efficient image pipelines. You'll learn private repositories, image scanning for vulnerabilities, lifecycle policies, and cross-account image sharing. Having a solid container image strategy is just as important as how you run them on Fargate.






Comments
Loading comments…