Skip to content

Intermediate · Containers in the cloud · topic 32 of 50 · 30 min

Amazon ECS and AWS Fargate

Explanation

Amazon ECS is AWS's own service for running containers. You describe a container in a task definition, run copies of it as tasks, and keep the right number running behind a load balancer with a service. With the Fargate launch type you never manage servers and pay per vCPU and GB of memory per second; with the EC2 launch type you run and pay for the instances yourself.

What ECS does

Running one container is easy. Running fifty, across several machines, restarting crashed ones, replacing old versions with new ones and spreading traffic across them is hard. Software that does this is called a container orchestrator. Amazon Elastic Container Service (ECS) is AWS's own orchestrator. It is simpler than Kubernetes and is tightly integrated with other AWS services. There is no extra charge for ECS itself: you pay for the compute your containers use.

The building blocks

TermMeaning
ClusterA logical group where your tasks and services run
Task definitionA JSON blueprint: image, CPU, memory, ports, environment, roles and logging. Each change creates a new revision (orders-api:1, orders-api:2 and so on)
TaskOne running copy of a task definition (one or more containers)
ServiceKeeps a desired count of tasks running, replaces failed ones, registers them with a load balancer and rolls out new revisions
json
{
  "family": "orders-api",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "cpu": "512",
  "memory": "1024",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/orders-api-task-role",
  "containerDefinitions": [
    {
      "name": "api",
      "image": "123456789012.dkr.ecr.ap-south-1.amazonaws.com/orders-api:1.0.0",
      "essential": true,
      "portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
      "environment": [{ "name": "APP_ENV", "value": "prod" }],
      "secrets": [{ "name": "DB_PASSWORD", "valueFrom": "arn:aws:ssm:ap-south-1:123456789012:parameter/orders/db-password" }],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/orders-api",
          "awslogs-region": "ap-south-1",
          "awslogs-stream-prefix": "api"
        }
      }
    }
  ]
}
A Fargate task definition: half a vCPU (512 CPU units), 1 GB of memory, one container, a secret from Parameter Store and logs to CloudWatch.

Read it top to bottom. cpu is in CPU units, where 1024 units is 1 vCPU, so 512 is half a vCPU. memory is in MiB. Fargate allows only certain CPU and memory combinations, so check the table in the documentation. networkMode awsvpc gives every task its own network interface and private IP address in your VPC, so security groups apply per task. Fargate always uses awsvpc.

Two roles: execution role and task role

This is the most common source of confusion. The task execution role is used by ECS and Fargate themselves, before and around your code: to pull the image from ECR, to send logs to CloudWatch, and to fetch the secrets listed in the task definition. The task role is used by your application code when it calls AWS, for example to read from S3 or write to DynamoDB.

Tip: Quick check: if the task never starts with an error about pulling the image or reading a secret, look at the execution role. If the app runs but gets AccessDenied when calling S3, look at the task role.

Services and rolling deployments

A service keeps a desired count of tasks running, for example 3. If a task crashes, the service starts a replacement. With a load balancer, the service registers each new task in a target group (with target type ip, because each task has its own IP) and the Application Load Balancer only sends traffic to tasks that pass the health check.

To release a new version, you register a new task definition revision and update the service. In a rolling deployment, ECS starts new tasks, waits for them to become healthy, then stops old ones. minimumHealthyPercent and maximumPercent control how many can be down or extra during the rollout, and the deployment circuit breaker can roll back automatically if new tasks keep failing.

bash
aws ecs create-cluster --cluster-name shop
aws ecs register-task-definition --cli-input-json file://taskdef.json
aws ecs create-service --cluster shop --service-name orders-api --task-definition orders-api:1 --desired-count 3 --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[subnet-0abc1234,subnet-0def5678],securityGroups=[sg-0123abcd],assignPublicIp=DISABLED}"
aws ecs update-service --cluster shop --service orders-api --task-definition orders-api:2
Create a cluster, register the blueprint, run 3 tasks as a service, then roll out revision 2.

Launch types: Fargate or EC2

FargateEC2 launch type
ServersNone to manage: AWS runs the computeYou run EC2 instances in the cluster and patch them
BillingPer second for the vCPU and memory each task requests (one-minute minimum)For the EC2 instances, whether they are full or empty
Good forMost web APIs and workers, small teams, spiky loadSteady high load packed tightly, GPUs, special instance types
SavingsFargate Spot for interruptible tasks; Savings PlansReserved Instances, Savings Plans, Spot Instances

Fargate also works with Amazon EKS, so the same serverless compute can run Kubernetes pods. Fargate prices differ by region and by CPU architecture (x86 or ARM), so take rates from the AWS pricing page for your region.

Logs and monitoring

With the awslogs log driver, everything your container prints to standard output goes to a CloudWatch Logs group. CloudWatch Container Insights adds CPU, memory and task-count metrics per service, and you can set alarms on them.

Careful: Common mistakes: mixing up the execution role and the task role; running tasks in private subnets with no NAT gateway or VPC endpoints, so they cannot reach ECR (the error says CannotPullContainerError); a security group that does not allow traffic from the load balancer; a health check path that returns 404, so ECS keeps killing healthy tasks; and choosing a CPU and memory pair Fargate does not support.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Amazon ECS and AWS Fargate · 1/7

Amazon ECS

Amazon E C S is AWS's own container orchestrator. It starts, restarts, scales and updates your containers.

Prefer a video by a teacher? Find free videos on “amazon ecs fargate tutorial task definition service” on YouTube ↗

In real life: An insurance claims API in Gurugram

An insurance company in Gurugram runs its claims API on ECS with Fargate in ap-south-1, across three Availability Zones. The service keeps 4 tasks running behind an Application Load Balancer during office hours, and a scheduled scaling action drops it to 2 at night. The task role allows only reading claim documents from one S3 bucket; the execution role pulls the image from ECR and reads the database password from Parameter Store. When a new release fails its health checks, the deployment circuit breaker rolls back to the previous revision before customers notice.

bash
aws ecs describe-services --cluster claims --services claims-api --query "services[0].[desiredCount,runningCount]"
Check desired versus running task counts.

Practice (0/3 done)

Task 1 · Code · Python

Write fargate_monthly_cost(vcpu, memory_gb, tasks, hours, vcpu_rate, gb_rate) that estimates a Fargate bill. vcpu and memory_gb are per task, tasks is how many run, hours is how long they run in the month, and the two rates are per vCPU-hour and per GB-hour (pass in the current rates for your region). Cost = vCPU-hours x vcpu_rate + GB-hours x gb_rate. Round to 2 decimal places.

Task 2 · Question

Your ECS task starts, but the app logs "AccessDenied" when it tries to read a file from S3. Which role should you fix?

Task 3 · Practice

Write a Fargate task definition (JSON) for a Node.js API image in ECR that listens on port 3000, needs 0.5 vCPU and 1 GB of memory, reads a database URL from Secrets Manager or Parameter Store, and logs to CloudWatch. Then write the aws ecs commands to create a service with 2 tasks in private subnets.

Quick quiz

Question 1

1.In ECS, what keeps a desired number of tasks running and replaces failed ones?

Question 2

2.How is Fargate billed?

Question 3

3.A task definition says "cpu": "1024". How much CPU is that?

Question 4

4.Tasks in a private subnet fail with CannotPullContainerError. What is a likely cause?

Question 5

5.When would the EC2 launch type make more sense than Fargate?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

In ECS, what keeps a desired number of tasks running and replaces failed ones?

Answer: A service

A service maintains the desired count and handles rolling deployments.

How is Fargate billed?

Answer: Per vCPU and GB of memory requested by each task, per second

Fargate charges for the vCPU and memory your tasks request, by the second with a one-minute minimum.

A task definition says "cpu": "1024". How much CPU is that?

Answer: One vCPU

1024 CPU units equal 1 vCPU.

Tasks in a private subnet fail with CannotPullContainerError. What is a likely cause?

Answer: There is no NAT gateway or VPC endpoint, so the tasks cannot reach ECR

To pull images, tasks need a route to ECR, through a NAT gateway or VPC endpoints.

When would the EC2 launch type make more sense than Fargate?

Answer: For a steady, heavy workload that needs GPUs or special instance types

The EC2 launch type gives you control of instance types such as GPUs, and can be cheaper for steady, tightly packed load.

Which is a PaaS option that can run web apps from code or containers without Kubernetes?Related

Answer: Azure App Service

Azure App Service (and AWS Elastic Beanstalk) are platforms as a service.

From Choosing where to run a container

Which EKS feature runs selected pods without any EC2 nodes to manage?Related

Answer: Fargate profiles

A Fargate profile selects pods by namespace and labels and runs them on Fargate.

From Managed Kubernetes: EKS, AKS and GKE

In the instance type r7g.xlarge, what does the g mean?Related

Answer: AWS Graviton (ARM) processor

The attribute g means a Graviton ARM processor. GPU instances are the g and p families, where the letter comes first.

From EC2: virtual servers in the cloud

A function uses 1,024 MB and runs for 500 ms. How many GB-seconds is one run?Related

Answer: 0.5

1,024 MB is 1 GB, and 500 ms is 0.5 seconds. 1 × 0.5 = 0.5 GB-seconds.

From Serverless with AWS Lambda

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Containers in the cloud” before its exam: Managed Kubernetes: EKS, AKS and GKE, Choosing where to run a container.
  2. Module 8 exam: Containers in the cloud · 12 questions · 20 min, without help. 4 topics of this module still to finish first.
  3. Then the next module, Infrastructure as code. 50 topics left in the course before the final exam.

← Previous: Containers, images and registries