AWS ECS – Docker Container service

In this blog, I will cover AWS ECS Docker Container service. ECS is an AWS product. This blog is part of my Docker for AWS series and uses the sample voting application for illustration.

AWS has EC2 Container service(ECS) for folks who want to deploy Docker containers in AWS infrastructure. For basics of AWS ECS, you can refer to my previous blog here. With ECS, Amazon provides its own scheduler to manage Docker containers. ECS integrates very well with other AWS services including load balancer, logging service, cloudformation templates etc. AWS recently introduced Application load balancer(ALB) that does L7 load balancing and this integrates well with ECS. Using ALB, we can load balance services directly across Containers. With ECS, users get charged for the EC2 instances and not for the Containers.

To demonstrate ECS usage, we will deploy voting service application in ECS cluster.

Following are the steps:

  • Create ECS IAM role that allows for EC2 instance to register to Container instance.
  • Create cluster from ECS menu. Multiple EC2 hosts can be part of the same cluster.
  • Create EC2 container instances and tie them to the cluster. We need to choose Container instances with ECS ami-id. In this customized EC2 instances, Amazon will install Docker and also install EC2 agent container that will do container health check and other house keeping.  I chose amzn-ami-2016.03.h-amazon-ecs-optimized(ecs optimized) AMI. As part of instance creation, we need to use the correct IAM role for the instance so that the instance can add itself to the ecs cluster.
  • Create task. A task can have 1 or more containers. A task is equivalent to docker-compose YML file.
  • Create service and tie it to either classic load balancer or application load balancer. Load balancer needs to be created before. Service can expose the application endpoint either internally or externally.

Following are more details of the steps above that I have executed:

Create IAM role
I created IAM role using AWS console. Following is the role that I have created:

$ aws iam list-attached-role-policies --role-name ecsServiceRole{
    "AttachedPolicies": [
            "PolicyName": "AmazonEC2ContainerServiceRole", 
            "PolicyArn": "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"

Create cluster
Following command creates ECS cluster:

aws ecs create-cluster --cluster-name myecscluster

At this point, there are no EC2 instances in the cluster. Following command lists the current clusters available:

$ aws ecs  list-clusters
    "clusterArns": [

Add EC2 instances to the cluster
Following command creates 2 ECS instances and adds to the cluster:

aws ec2 run-instances --image-id ami-2d1bce4d --count 2 --instance-type t2.micro --key-name lak-oregon --security-groups "default" --iam-instance-profile Name=ecsaccess --user-data file://

Following is the content of “” script:

echo ECS_CLUSTER=myecscluster >> /etc/ecs/ecs.config

The script helps in tying the EC2 instance to “myecscluster”.

Following command shows that there are 2 instances in the ECS cluster:

$ aws ecs list-container-instances --cluster myecscluster{
    "containerInstanceArns": [

Following output shows the Docker version running in EC2 instance:

$ docker --version
Docker version 1.11.2, build b9f10c9/1.11.2

Register tasks
Following command registers the “voting” task with 2 Containers:

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

Following is the content of “voting.json” that describes the 2 containers. This is equivalent to “docker-compose.yml” that Docker provides.

  "containerDefinitions": [
      "memory": 64,
      "essential": true,
      "name": "client",
      "environment": [
          "name": "tty",
          "value": "true"
      "links": [
      "image": "smakam/myubuntu:v4",
      "command": [
      "memory": 64,
      "portMappings": [
          "hostPort": 0,
          "containerPort": 80,
          "protocol": "tcp"
      "essential": true,
      "name": "vote",
      "image": "instavote/vote:latest"
  "family": "myvotingapp"

In the above task file, we have created “client” and “vote” containers and linked them. Also, we have exposed port 80 from “vote” container.

Create application load balancer(ALB)
I have created Application load balancer using AWS console. Following is the ALB that I have created:

$ aws elbv2 describe-load-balancers --names myvotingapplb
    "LoadBalancers": [
            "VpcId": "vpc-794f191c", 
            "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:591143063013:loadbalancer/app/myvotingapplb/9d0b9bcf68877301", 
            "State": {
                "Code": "active"
            "DNSName": "", 
            "SecurityGroups": [
            "LoadBalancerName": "myvotingapplb", 
            "CreatedTime": "2016-08-24T14:26:28.910Z", 
            "Scheme": "internet-facing", 
            "Type": "application", 
            "CanonicalHostedZoneId": "Z1H1FL5HABSF5", 
            "AvailabilityZones": [
                    "SubnetId": "subnet-0c6e4969", 
                    "ZoneName": "us-west-2a"
                    "SubnetId": "subnet-1a8cf66d", 
                    "ZoneName": "us-west-2b"
                    "SubnetId": "subnet-df8a1686", 
                    "ZoneName": "us-west-2c"

When we create ALB, we do not bind to the instance at this point. We will bind it later as part of the service creation.

Create service
The last step is creation of Service. The service gets exposed through the application load balancer. Following command creates the service:

aws ecs create-service --service-name myvotingapp --cli-input-json file://votingservice.json

Following is the content of “votingservice.json”. This specifies the number of container instance and the target group for ALB.

    "serviceName": "votingservice",
    "taskDefinition": "myvotingapp",
    "cluster": "myecscluster",
    "loadBalancers": [
            "targetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:591143063013:targetgroup/myvotingapp/8b5f372d39040605",
            "containerName": "vote",
            "containerPort": 80
    "desiredCount": 2,
    "role": "ecsServiceRole"

Following output shows running Containers in EC2 “node1”:

$ docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                   NAMES
68d025ca83ce        smakam/myubuntu:v4               "ping"        37 minutes ago      Up 37 minutes                               ecs-myvotingapp-14-client-e094e1b58df1a9bc0d00
07ba9045dce3        instavote/vote:latest            "gunicorn app:app -b "   38 minutes ago      Up 38 minutes>80/tcp   ecs-myvotingapp-14-vote-8aaac68985efb3a6a601
bffe3525ff10        amazon/amazon-ecs-agent:latest   "/agent"                 47 minutes ago      Up 47 minutes                               ecs-agent

Following output shows running Containers in EC2 “node2”:

$ docker ps
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS                   NAMES
473994b0e95f        smakam/myubuntu:v4               "ping"        38 minutes ago      Up 38 minutes                               ecs-myvotingapp-14-client-a0bc8d84d8a3fdc8a801
bf0248b47904        instavote/vote:latest            "gunicorn app:app -b "   38 minutes ago      Up 38 minutes>80/tcp   ecs-myvotingapp-14-vote-96c88acfcc8aa3b4b401
593ed19b2219        amazon/amazon-ecs-agent:latest   "/agent"                 48 minutes ago      Up 48 minutes                               ecs-agent

“ecs-agent” is the system container, others are user containers.

Following output shows that accessing the ALB distributing the load between the 2 Containers:

$ curl | grep -i "container id"
          Processed by container ID 07ba9045dce3
$ curl | grep -i "container id"
          Processed by container ID bf0248b47904

For multi-container application, ECS task and service terminology is little confusing. I have posted the query here and I have not received response.


One thought on “AWS ECS – Docker Container service

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s