Skip to content
AWS aws containers 6 min read

What is Amazon ECS?

Amazon ECS (Elastic Container Service) is AWS’s own service for running containers at scale. A container is a lightweight, self-contained package that bundles your application code with everything it needs to run. ECS takes care of starting those containers, keeping the right number of them running, replacing ones that crash, and connecting them to load balancers and networking. It is the simplest way to run containers on AWS without learning Kubernetes, and because AWS built it, it plugs straight into the rest of the platform.

Why ECS exists

Once you package an app into a container, you face a new problem: who actually runs it? You do not want to manually start containers on servers, watch for crashes, and wire up networking by hand. That job is called container orchestration, and ECS is AWS’s native orchestrator.

ECS gives you a control plane (the brain that decides what runs where) for free. You describe what you want to run, and ECS makes reality match that description. If a container dies, ECS launches a replacement. If you ask for five copies, ECS keeps five copies running. You never SSH into a server to babysit containers.

When to use ECS: you are an AWS-focused team, you want containers running in production quickly, and you do not need the broad open-source ecosystem of Kubernetes. When NOT to use it: you need to run the same setup across multiple clouds, or your team already has deep Kubernetes skills and tooling. In those cases look at EKS instead.

The three core building blocks

ECS has only a few concepts to learn. This is the main reason teams pick it over the heavier Kubernetes model.

ConceptWhat it isReal-world analogy
ClusterA logical grouping that holds your running containersThe “environment” your apps live in
Task definitionA blueprint describing which container image to run, CPU/memory, ports, and environment variablesA recipe
TaskOne running instance of a task definition (one or more containers running together)A cooked dish from the recipe
ServiceA controller that keeps a set number of tasks running and ties them to a load balancerA waiter who makes sure dishes keep coming

A task definition is just JSON. You register it once, then run it as standalone tasks (good for batch jobs) or as a long-running service (good for web APIs that must stay up).

Tip: Think of a task definition as the immutable template and the service as the live manager. You version task definitions (revision 1, 2, 3…) and tell the service which revision to run. Rolling back a bad deploy is just pointing the service at an older revision.

How ECS runs your containers: two launch types

ECS does not run containers in thin air; it needs compute to run them on. You choose one of two launch types.

Launch typeWho manages the serversBest forCost model
FargateAWS (serverless, no servers to see)Most workloads; teams who do not want to manage serversPay per vCPU-second and GB-second your tasks use
EC2You (you run and patch the EC2 instances)High, steady volume; need GPUs or special instance typesPay for the EC2 instances whether busy or idle

For most beginners, Fargate is the right default. AWS provisions and patches the underlying machines invisibly, and you pay only for the resources your tasks request. A small Fargate task (0.25 vCPU, 0.5 GB) running 24/7 costs roughly 9 USD per month in us-east-1, which makes it cheap to start.

ECS vs EKS at a high level

Both ECS and EKS run containers on AWS, but they sit at very different complexity levels.

Amazon ECSAmazon EKS
OrchestratorAWS-proprietaryManaged Kubernetes (open source)
Learning curveLow — a handful of conceptsHigh — full Kubernetes API and ecosystem
Control plane costFreeAbout 73 USD per cluster per month
PortabilityAWS onlyRuns the same anywhere Kubernetes runs
Best forAWS-only teams who want simplicityMulti-cloud teams or existing Kubernetes shops

Gotcha — vendor lock-in is the real tradeoff. ECS is AWS-proprietary. The task definitions, CLI commands, and operational knowledge you build do not transfer to Google Cloud, Azure, or your own data center. Kubernetes (and therefore EKS) is portable by design, so the same manifests run elsewhere. You are trading portability for simplicity. For an AWS-only team that wants to ship fast, that trade is usually worth it; for a team that may need to leave AWS one day, it is a real cost to weigh up front.

A first deployment

Here is the shape of getting an app running on ECS with Fargate. We will create a cluster, then later you register a task definition and run a service.

Create a cluster (Console)

  1. Open the ECS console and choose Clusters in the left menu.
  2. Click Create cluster.
  3. Enter a name, for example prod-web.
  4. Under Infrastructure, leave AWS Fargate (serverless) selected.
  5. Click Create.

Create a cluster (CLI)

aws ecs create-cluster \
  --cluster-name prod-web \
  --region us-east-1

Output:

{
    "cluster": {
        "clusterArn": "arn:aws:ecs:us-east-1:111122223333:cluster/prod-web",
        "clusterName": "prod-web",
        "status": "ACTIVE",
        "registeredContainerInstancesCount": 0,
        "runningTasksCount": 0,
        "activeServicesCount": 0
    }
}

Register a task definition (CLI)

The task definition points at a container image, usually stored in Amazon ECR (Elastic Container Registry, AWS’s private image store). Save this as task-def.json:

{
  "family": "web-api",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "containerDefinitions": [
    {
      "name": "web",
      "image": "111122223333.dkr.ecr.us-east-1.amazonaws.com/web-api:1.0",
      "portMappings": [{ "containerPort": 8080, "protocol": "tcp" }],
      "essential": true
    }
  ]
}

Register it:

aws ecs register-task-definition \
  --cli-input-json file://task-def.json \
  --region us-east-1

Output:

{
    "taskDefinition": {
        "taskDefinitionArn": "arn:aws:ecs:us-east-1:111122223333:task-definition/web-api:1",
        "family": "web-api",
        "revision": 1,
        "status": "ACTIVE"
    }
}

The :1 at the end is the revision. Every change you register bumps this number, giving you a clean history to roll back to.

Run it as a service (CLI)

aws ecs create-service \
  --cluster prod-web \
  --service-name web-api-svc \
  --task-definition web-api:1 \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-0a1b2c3d],securityGroups=[sg-0a1b2c3d],assignPublicIp=ENABLED}" \
  --region us-east-1

ECS now keeps two copies of your task running. Kill one and ECS launches a replacement automatically.

Best Practices

  • Default to Fargate unless you have a clear cost or hardware reason to manage EC2 instances yourself.
  • Keep task definitions small and versioned — never edit a running container by hand; register a new revision and update the service.
  • Store images in Amazon ECR in the same region as your cluster to cut latency and data-transfer cost.
  • Always run production services with desired-count of 2 or more across multiple subnets so a single failure does not take you down.
  • Use IAM task roles so each task gets only the permissions it needs, instead of baking long-lived credentials into images.
  • Front your services with an Application Load Balancer and let ECS register and deregister tasks automatically during deploys.
  • Right-size CPU and memory: over-provisioning Fargate tasks wastes money because you pay for what you request, not what you use.
Last updated June 15, 2026
Was this helpful?