AWS DevOps Pro Certification Blog Post Series: AWS ECS


This is part of the blog post series: AWS DevOps Pro Certification

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.

What?

AWS ECS ...

Additional resources:

Why?

When?

How?

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!

Pre-requisites

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 dev.to-ers</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"
}
EOF

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

curl $ECS_TASK_PUBLIC_IP

# tear down

aws ecs stop-task --task $ECS_TASK_ID --cluster $ECS_CLUSTER_NAME
aws ecs delete-cluster --cluster $ECS_CLUSTER_NAME

API and CLI features and verbs

Features

Verbs (CRUD)

Outliers

AWS DevOps Pro Certification Blog Post Series



Tweet