DEV Community

Cover image for AWS DevOps Pro Certification Blog Post Series: AWS ECS
Mark Sta Ana
Mark Sta Ana

Posted on • Originally published at on

AWS DevOps Pro Certification Blog Post Series: AWS ECS

Photo by chuttersnap on Unsplash

Caveat emptor

Using AWS costs money, some of these services may not be part of the AWS Free Tier. You can keep costs down by tearing down anything you've created whilst learning, but it's still possible to run up a hefty bill so pay attention to the instances you setup!

I'm very lucky to be able to use my employer's AWS account. You should ask your place of work if a similar arrangement can be made as part of your study.

Velocius quam asparagi conquantur

The format of the blog posts is liable to change as I try to refine my mental model of each domain, so be sure to revisit the blog posts on a regular basis.



  • is Amazon's Docker managed service. Naturally, you also get a container registry service in the form of Elastic Container Registry (ECR).
  • comes in two varieties (launch types): EC2 or Fargate.
    • EC2 based clusters as the name implies uses EC2 instances as Docker hosts for containers.
    • You pay for the resources spun up i.e. EC2 instances and/or EBS volumes.
    • You're also responsible for the upkeep of the EC2 instances (patching, monitoring and making secure).
    • Fargate abstracts away EC2 instances (much like serverless functions).
    • You pay for the vCPU (virtual CPU) and memory resources the container uses. This is charged at per second rate (with a minimum charge of a minute).
    • Fargate is only available to few regions (13 at the time of writing this)
    • There's no EC2 instances to maintain, just your tasks.
  • is not a Kubernetes managed services, this is a separate offering with the catchy name of Elastic Container Service for Kubernetes Service (EKS)

Additional resources:


  • As with all managed services, you want to focus on the functionality rather than the upkeep of a service.
  • With Docker becoming the lingua franca of the Cloud you can utilise 3rd party images and build solutions in a build block manner. Granted, Amazon has been using this modularized concept for many years (OpsWorks and Elastic Beanstalk) before Docker became mainstream.


  • Microservices and batch jobs are good workloads for a cluster.
  • You want to migrate away from Docker managed through on-premises infrastructure or EC2 instances that are not ECS managed.


For this section, we're going to use Fargate rather than an EC2 based ECS cluster.

This is mostly to reduce the additional complexity of provisioning the EC2 instances that will join the ECS cluster. This guide is loosely based around the Fargte tutorial in the Developer Guide. I've just removed the part about setting up a service and ran a task with public IP we could visit to test.

That said, for day to day work you may find yourself still using EC2 based cluster until Fargate is available across all regions. You may also still find yourself using EC2 based clusters from a cost-saving perspective. If anyone has a calculator they've created when it makes more sense to go with the Fargate launch-type over EC2, please share in the comments or @ me on Twitter!


  • A VPC with at least one subnet that has inbound and outbound access to the internet.
  • A suitable security group as per the previous point
export ECS_CLUSTER_NAME=your-cluster-name
export ECS_SECURITY_GROUP=your-security-group
export ECS_SUBNETS=yoursubnet

# create a cluster
aws ecs create-cluster --cluster-name $ECS_CLUSTER_NAME

# register a task

cat <<EOF > fargate-task.json
  "family": "sample-fargate",
  "networkMode": "awsvpc",
  "containerDefinitions": [
      "name": "fargate-app",
      "image": "httpd:2.4",
      "portMappings": [
          "containerPort": 80,
          "hostPort": 80,
          "protocol": "tcp"
      "essential": true,
      "entryPoint": ["sh", "-c"],
      "command": [
        "/bin/sh -c \"echo '<html> <head> <title>Hello</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Hello, world!</h1> </div></body></html>' >  /usr/local/apache2/htdocs/index.html && httpd-foreground\""
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512"

aws ecs register-task-definition \
  --cli-input-json file://fargate-task.json

# create a task, assign it to our network and enable the public IP

aws ecs run-task \
  --cluster $ECS_CLUSTER_NAME \
  --task-definition sample-fargate:2 \
  --count 1 \
  --launch-type "FARGATE" \
  --network-configuration "awsvpcConfiguration={subnets=[$ECS_SUBNETS],securityGroups=[$ECS_SECURITY_GROUP],assignPublicIp="ENABLED"}"

# list tasks

aws ecs list-tasks --cluster $ECS_CLUSTER_NAME

# describe the task

export ECS_TASK_ID=$(aws ecs list-tasks --cluster $ECS_CLUSTER_NAME --query "taskArns" --output text)
aws ecs describe-tasks --cluster $ECS_CLUSTER_NAME --tasks $ECS_TASK_ID

# get the public IP of the task (well, the one bound to the ENI)

export ECS_TASK_NETWORK_ID=$(aws ecs describe-tasks --cluster $ECS_CLUSTER_NAME --tasks $ECS_TASK_ID --query 'tasks[*].attachments[*].details[?name==`networkInterfaceId`].value' --output text)

export ECS_TASK_PUBLIC_IP=$(aws ec2 describe-network-interfaces --network-interface-ids $ECS_TASK_NETWORK_ID --query "NetworkInterfaces[*].PrivateIpAddresses[*].Association.PublicIp" --output text)

# test


# tear down

aws ecs stop-task --task $ECS_TASK_ID --cluster $ECS_CLUSTER_NAME
aws ecs delete-cluster --cluster $ECS_CLUSTER_NAME
Enter fullscreen mode Exit fullscreen mode

API and CLI features and verbs


  • Clusters
  • Services
  • Task Sets

Verbs (CRUD)

  • create
  • describe/list (cluster/services)
  • update (service/task-set)
  • delete


  • delete-account-setting
  • delete-attributes
  • deploy
  • deregister-container-instance
  • deregister-task-definition
  • describe-container-instances
  • describe-task-definition
  • describe-tasks
  • discover-poll-endpoint
  • list-account-settings
  • list-attributes
  • list-container-instances
  • list-tags-for-resource
  • list-task-definition-families
  • list-task-definitions
  • list-tasks
  • put-account-setting
  • put-account-setting-default
  • put-attributes
  • register-container-instance
  • register-task-definition
  • run-task
  • start-task
  • stop-task
  • submit-container-state-change
  • submit-task-state-change
  • tag-resource
  • untag-resource
  • update-container-agent
  • update-container-instances-state
  • update-service-primary-task-set
  • wait

Unsplash path (what terms I used to get to the cover image): container

To go to the next part of the series, click on the grey dot below which is next to the current marker (the black dot).

Top comments (0)