You push the image, create the service, and the first tasks never reach RUNNING. They stop with a ResourceInitializationError: unable to pull secrets or registry auth. The image is fine. The tasks sit in private subnets with no route to Amazon ECR or Secrets Manager, so Fargate cannot start them.
Many ECS on Fargate problems look like this: the containers work, and the network, roles or load balancer settings around them do not. This post walks through a production web service on Amazon ECS with AWS Fargate, from networking and load balancing to IAM, scaling, deployments and ECS vs EKS, with a diagram you can copy.
ECS concepts in one table
| Concept | What it is | In the example |
|---|---|---|
| Cluster | A logical group of services and tasks | prod |
| Task definition | Versioned blueprint: image, CPU, memory, ports, roles, secrets, logging | orders-api:42 |
| Task | A running copy of a task definition; on Fargate it has its own kernel, memory and network interface | 2 to 10 copies |
| Service | Keeps the desired task count, registers tasks with the load balancer, runs deployments | orders-api |
| Capacity provider | Where tasks run: FARGATE, FARGATE_SPOT, EC2 Auto Scaling groups or ECS Managed Instances |
FARGATE and FARGATE_SPOT |
The cluster is not a network boundary: tasks run in the subnets you name, behind their own security groups. ECS charges nothing for orchestration; Fargate bills each task's vCPU, memory and storage per second, with a one-minute minimum.
Networking: one ENI per task
Fargate tasks always use the awsvpc network mode: each task gets its own elastic network interface (ENI), a private IP from its subnet and its own security groups (Fargate task networking). Three consequences:
- Subnets need room. Each task takes one IP, and AWS reserves five per subnet. Sixty tasks across two AZs means 30 per subnet, and a rolling deployment at 200% briefly needs 60. A /24 (251 usable) fits; a /27 (27 usable) does not.
- Security groups work per task. Open the container port only to the load balancer's group, and port 5432 on the database only to the tasks' group.
- Tasks need a path to AWS APIs. Before your code runs, Fargate pulls the image, fetches secrets and starts sending logs through the task's ENI.
From a private subnet, that path is a NAT gateway or VPC endpoints (US East prices at the time of writing, November 2026):
| Path | You create | Cost | Trade-off |
|---|---|---|---|
| NAT gateway | One per AZ, or one regional NAT gateway | $0.045 per AZ-hour plus $0.045 per GB | Also reaches third-party APIs |
| VPC endpoints | Interface endpoints ecr.api, ecr.dkr, logs, secretsmanager, plus the S3 gateway endpoint |
$0.01 per endpoint per AZ-hour plus $0.01 per GB; the S3 gateway is free | No internet path at all |
Do not skip the S3 gateway endpoint: ECR stores image layers in S3 (ECR interface endpoints). Four interface endpoints in two AZs cost about $58 a month before data (8 × $0.01 × 730 hours), close to two NAT gateways at $66, so endpoints win on data charges and privacy, NAT on reach. Since November 2025, a regional NAT gateway spans AZs by itself and needs no public subnet. Public IPs on tasks also work, but leave every task one security group rule away from the internet. The AWS VPC diagram covers routes and NAT placement.
The load balancer: target groups and health checks
The ALB needs subnets in at least two AZs, each a /27 or larger with eight free addresses. Because an awsvpc task is an ENI, not an EC2 instance, the target group's type must be ip. Use one target group per service; ECS registers and deregisters the tasks.
| Setting | Default | Consider |
|---|---|---|
| Health check interval | 30 s | 5 s if the service starts in under 10 s (AWS's suggestion) |
| Unhealthy threshold | 2 checks | A failing task is out in about a minute |
| Healthy threshold | 5 checks | New targets need only one passing check |
| Deregistration delay | 300 s | 30 s or less for short requests; old tasks can drain this long |
healthCheckGracePeriodSeconds |
0 | Cover startup time, or slow starters get replaced in a loop |
Since November 2025, ECS Express Mode can create this ALB, HTTPS and scaling setup from a container image. The load balancer diagram covers health checks and draining in general.
IAM: the execution role and the task role
Two roles, two jobs:
- The task execution role is used by ECS and the Fargate agent, not your code: it pulls the image, writes logs and reads the secrets named in the task definition (task execution role).
AmazonECSTaskExecutionRolePolicycovers ECR and logs; addsecretsmanager:GetSecretValueyourself, andkms:Decryptfor a customer managed key. - The task role is what your code uses through the AWS SDK, for S3 or SQS, and what ECS Exec needs.
Secrets arrive as environment variables:
"secrets": [{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:111122223333:secret:prod/orders/db-AbCdEf:password::"
}]
ECS reads the value when the container starts. A rotated secret does not reach running tasks, so redeploy after rotation or let the app read the secret with its task role. Picking one JSON key, as above, needs platform version 1.4.0, the current LATEST.
Scaling: target tracking and Fargate Spot
For Service Auto Scaling, start with target tracking on ECSServiceAverageCPUUtilization, ECSServiceAverageMemoryUtilization or ALBRequestCountPerTarget. It scales out fast, scales in slowly and pauses scale-in during deployments; with several policies, it scales in only when all agree. Keep at least one task per AZ.
Fargate Spot costs up to 70% less. When AWS reclaims the capacity, the task gets a two-minute warning, as an EventBridge event with the stop code SpotInterruption and as a SIGTERM (Fargate capacity providers). stopTimeout maxes out at 120 seconds, and Fargate never falls back to regular capacity by itself, so keep a base:
"capacityProviderStrategy": [
{ "capacityProvider": "FARGATE", "base": 2, "weight": 1 },
{ "capacityProvider": "FARGATE_SPOT", "weight": 1 }
]
The first two tasks always run on regular Fargate; the rest split one to one. A single-task service on Spot simply stops until capacity returns.
Deployments: rolling, blue/green, linear and canary
Rolling is the default: with minimumHealthyPercent 100 and maximumPercent 200, ECS starts new tasks before stopping old ones. Turn on the deployment circuit breaker with rollback; by default it fails a deployment once failed tasks reach half the desired count (at least 3, at most 200). CloudWatch alarms can trigger the same rollback.
Since July 2025, ECS runs blue/green deployments itself, without CodeDeploy, and since October 2025 linear and canary too. They start the new revision behind a second target group, shift listener traffic and keep the old tasks for a bake time, so rollback is a traffic switch.
| Strategy | Traffic shift | Rollback | Extra capacity |
|---|---|---|---|
| Rolling | Tasks replaced in batches | Redeploy | Up to maximumPercent |
| Blue/green | All at once, after optional test traffic | Switch back | 2x |
| Linear | Equal steps, such as 10% every few minutes | Switch back | 2x |
| Canary | A small share, then the rest | Switch back | 2x |
Lambda or pause hooks can gate each stage. Target tracking on ALBRequestCountPerTarget is not supported with blue/green. The deployment strategies diagram compares the patterns.
Observability
The awslogs driver needs awslogs-group, awslogs-region and, on Fargate, awslogs-stream-prefix. Since June 25, 2025, it defaults to non-blocking mode with a 10 MB buffer: a CloudWatch hiccup no longer freezes your app, but a full buffer drops lines. Add Container Insights with enhanced observability, ECS Exec for shells, and an EventBridge rule on task state changes; the stopped reason says why a task died. For traces, run an OpenTelemetry Collector as a sidecar in the task; it is the agent tier of a pipeline for logs, metrics and traces with OpenTelemetry.
ECS vs EKS
| Amazon ECS | Amazon EKS | |
|---|---|---|
| Control plane | Free | $0.10 per cluster-hour, about $73 a month |
| API | AWS task definitions and services | Kubernetes, Helm, operators |
| Compute | Fargate, EC2, ECS Managed Instances | Fargate, EC2 node groups, EKS Auto Mode |
| Upgrades | None for the control plane | 14 months of standard support per Kubernetes version, then $0.60 per cluster-hour |
| Built-in deployments | Rolling, blue/green, linear, canary | Rolling; others through tools such as Argo Rollouts |
Prices are from the EKS pricing page at the time of writing (November 2026). Choose EKS when you need Kubernetes portability or its ecosystem; the Kubernetes architecture diagram shows that picture. For short, event-driven work, Lambda-based serverless designs need no long-running service at all.
The ECS on Fargate diagram
Diagram contents
- VPC
- Public subnet · AZ a
- Public subnet · AZ b
- Private subnet · AZ a
- Private subnet · AZ b
- Application Load Balancer
- orders-api task
- RDS for PostgreSQL
- VPC endpoints
- Users
- Amazon ECR
- Secrets Manager
- CloudWatch Logs
- HTTPS 443
- HTTP 8080
- SQL 5432
- image pull
- secrets at start
- awslogs
How to read it:
- AZs are rows. Each has a public and a private subnet. The ALB, RDS and the endpoints sit between the rows because each spans both AZs: an ALB node in each public subnet, a Multi-AZ standby for the database.
- Solid blue is the request path: HTTPS to the ALB, HTTP 8080 to one task per AZ, SQL on port 5432.
- Dashed purple is platform traffic: the image pull, secrets and logs, sent by Fargate with the task execution role through the VPC endpoints.
- Only the public subnets route 0.0.0.0/0 to the internet gateway.
- The Markdown block lists the service settings.
Drawing ECS diagrams clearly
- Put tasks inside per-AZ subnets. An "ECS cluster" box around everything hides where tasks run and what they can reach.
- Draw one task per AZ, with the scaling range next to it.
- Show the path to ECR, Secrets Manager and CloudWatch Logs. A missing path is a common reason tasks fail to start.
- Label the ALB edge with the port and target type, and name the role behind the dashed edges in a legend.
- Leave out sidecars, CI/CD and DNS records unless the diagram is about them.
The AWS three-tier architecture template has the same VPC layout with EC2.
Build it in Archboard
- Sign in with Google or GitHub and create a diagram.
- Add a VPC from the Network pack and four Subnet nodes inside it, a public and a private one for each AZ.
- Add a Cloud LB from the Cloud pack between the public subnets, and Text notes in the public subnets for the route and the ALB node.
- Add a Compute node from the Cloud pack in each private subnet, with the task size in the instance type field.
- Between the private subnets, add a Managed DB with high availability on and a Cloud resource for the VPC endpoints, both from the Cloud pack.
- Outside the VPC, add Internet from the Network pack, Registry from the Docker pack, Vault from the Security pack and Logs from the DevOps pack.
- Draw labeled edges, dashed for platform traffic, and add a Markdown block from the Core pack with the settings.
The CloudFormation to diagram and Terraform to diagram tools turn existing stack code into a first draft; when drawing the service from Terraform, trim the draft and add the request path by hand.
The example uses 15 diagram nodes, within the Free plan.
FAQ
Does Fargate require the awsvpc network mode?
Yes. Every Fargate task gets its own network interface and private IP address, which is why its target groups must use the ip target type.
What is the difference between the ECS task role and the task execution role? The execution role lets ECS start the task: pull the image, fetch secrets, send logs. The task role is what your application code uses for its own AWS calls.
Do Fargate tasks in private subnets need a NAT gateway? Not for AWS services. Interface endpoints for ECR, CloudWatch Logs and Secrets Manager, plus the S3 gateway endpoint, are enough. You need NAT only to reach the internet.
Does ECS support blue/green deployments without CodeDeploy? Yes. ECS has run blue/green natively since July 2025, and linear and canary since October 2025, with bake times, lifecycle hooks and alarm-based rollback.
Is ECS cheaper than EKS? For the control plane, yes: ECS has no orchestration fee, while an EKS cluster costs $0.10 per hour in standard support. Fargate and EC2 instance prices are the same under both.