Containers on ECS and Fargate

Amazon Web Services · Practical · 16 min

ECS on Fargate is the simplest production path from a container image to a scalable, load-balanced service on AWS.

Amazon ECR is the private image registry. Authenticate Docker with aws ecr get-login-password | docker login --password-stdin <account>.dkr.ecr.<region>.amazonaws.com, then tag and push. Enable scan on push and use lifecycle policies to expire old images.

Amazon ECS concepts:

  • A task definition is the versioned blueprint: containers, image, CPU and memory, ports, environment, secrets (from Secrets Manager or Parameter Store), log configuration and health check, plus two IAM roles: the task role your code uses and the task execution role ECS uses to pull images, fetch secrets and write logs.
  • A task is a running instance of a task definition.
  • A service keeps N tasks running, registers them with a load balancer target group, replaces failed tasks, scales with Application Auto Scaling and performs deployments.
  • A cluster groups services and capacity.

Capacity comes from Fargate (serverless: pay per task vCPU and memory, no instances to patch) or EC2 capacity providers (cheaper at scale, GPUs, more control). Fargate Spot runs interruptible tasks at a discount.

With the awsvpc network mode (required on Fargate) each task gets its own ENI, private IP and security group, so SG-to-SG rules work per service.

Deployments are rolling by default; enable the deployment circuit breaker with rollback so a bad image is automatically reverted. ECS Service Connect adds service discovery and traffic metrics between services.

Example

{
  "family": "orders-api",
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "cpu": "512",
  "memory": "1024",
  "runtimePlatform": {"cpuArchitecture": "ARM64", "operatingSystemFamily": "LINUX"},
  "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::111122223333:role/orders-api-task",
  "containerDefinitions": [{
    "name": "api",
    "image": "111122223333.dkr.ecr.eu-west-1.amazonaws.com/orders-api:1.4.2",
    "portMappings": [{"containerPort": 8080}],
    "secrets": [{"name": "DB_PASSWORD",
      "valueFrom": "arn:aws:secretsmanager:eu-west-1:111122223333:secret:prod/orders/db-AbCdEf:password::"}],
    "logConfiguration": {"logDriver": "awslogs", "options": {
      "awslogs-group": "/ecs/orders-api", "awslogs-region": "eu-west-1",
      "awslogs-stream-prefix": "api"}},
    "healthCheck": {"command": ["CMD-SHELL", "curl -f http://localhost:8080/healthz || exit 1"],
                    "interval": 30, "retries": 3}
  }]
}

Remember

  • ECR stores images; ECS runs them from versioned task definitions
  • Service = desired count + load balancer + deployments
  • Task role for your code, task execution role for ECS itself
  • Fargate removes servers; awsvpc gives each task its own ENI and SG

Watch out for

  • Using mutable tags like latest in task definitions, so you can't tell or roll back what is running.

Check yourself

  1. Your container can't read from S3 but logs and image pulls work. Which role most likely lacks permission?
  2. What does the deployment circuit breaker do?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html