Best Practices

Practical guidelines for secure, reliable, and cost-effective ECS in production.

A checklist to keep production ECS healthy:

Security

  • Use separate task roles (app permissions) and execution roles (pull images, write logs).
  • Keep secrets in Secrets Manager or SSM, never in plain env vars.
  • Run tasks in private subnets with least-privilege security groups.

Reliability

  • Spread tasks across multiple Availability Zones.
  • Define health checks and set sensible deployment percentages.
  • Enable Container Insights and alarms.

Cost

  • Right-size CPU and memory; use Fargate Spot or EC2 for savings.
  • Scale down non-production environments when idle.

Example

Example · json
{
  "family": "web",
  "taskRoleArn": "arn:aws:iam::123456789012:role/webAppRole",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "networkMode": "awsvpc",
  "cpu": "512",
  "memory": "1024",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "web:9",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80
        }
      ]
    }
  ]
}

When to use it

  • A security team mandates that all ECS task definitions use non-root users and read-only root file systems to reduce the blast radius of a container compromise.
  • A FinOps team tags every ECS service and task definition with cost-center tags so spend is attributed correctly in AWS Cost Explorer.
  • A reliability team enables the deployment circuit breaker on every ECS service so bad deployments automatically roll back instead of requiring manual intervention.

More examples

Run Container as Non-Root User

Runs the container as UID 1000 with a read-only root filesystem, mounting a writable /tmp volume so the app cannot modify the container image layer.

Example · json
{
  "name": "api",
  "image": "my-api:latest",
  "user": "1000:1000",
  "readonlyRootFilesystem": true,
  "mountPoints": [
    {"sourceVolume": "tmp", "containerPath": "/tmp"}
  ]
}

Enable Circuit Breaker on All Services

Iterates over every service in the cluster and enables the deployment circuit breaker with automatic rollback on each one.

Example · bash
for SVC in $(aws ecs list-services --cluster prod --query 'serviceArns[]' --output text); do
  aws ecs update-service \
    --cluster prod \
    --service "$SVC" \
    --deployment-configuration \
      'deploymentCircuitBreaker={enable=true,rollback=true}'
done

Propagate Tags to Tasks

Enables ECS-managed tag propagation so all cost-allocation tags applied to the service are automatically copied to every task it launches.

Example · bash
aws ecs update-service \
  --cluster prod \
  --service api \
  --enable-ecs-managed-tags \
  --propagate-tags SERVICE \
  --tags key=Team,value=platform key=CostCenter,value=engineering

Discussion

  • Be the first to comment on this lesson.