Launch ECS container using AWS ECS CLI
The Amazon ECS Command Line Interface (CLI) is a command line tool for Amazon Elastic Container Service (Amazon ECS) that provides high-level commands to simplify creating, updating, and monitoring clusters and tasks from a local development environment.
Make sure you do this setup first:
Install AWS ECS CLI
Install:
mkdir -p ~/ecs-cli
pushd ~/ecs-cli
# Download
curl -Lo ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest
curl -Lo ecs-cli.asc https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-darwin-amd64-latest.asc
# Verify signature
gpg --keyserver hkp://keys.gnupg.net --recv BCE9D9A42D51784F
gpg --verify ecs-cli.asc ecs-cli
# Copy to path
sudo cp ecs-cli /usr/local/bin
sudo chmod a+x /usr/local/bin/ecs-cli
popd
Test:
Define Variables
ECS CLI Setup
Configuration information is stored in the
~/.ecs
directory on macOS and Linux systems and inC:\Users\<username>\AppData\local\ecs
on Windows systems.
Create a profile using your access key and secret key:
export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id)
export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key)
export AWS_REGION=$(aws configure get region)
ecs-cli configure profile --profile-name swift
ECS Cluster Configuration
Create a cluster configuration:
export AWS_REGION=$(aws configure get region)
ecs-cli configure \
--config-name test-ecs \
--region $AWS_REGION \
--cluster test-ecs \
--default-launch-type EC2
ecs-cli configure default --config-name test-ecs
Launch ECS Cluster
This will take a few minutes to complete:
ecs-cli up \
--ecs-profile swift \
--cluster-config test-ecs \
--keypair aws-ec2-key \
--capability-iam \
--instance-type t2.micro \
--size 1 \
--port 22
In addition to EC2 Instances, other resources created by default include:
- Autoscaling Group
- Autoscaling Launch Configuration
- EC2 VPC
- EC2 Internet Gateway
- EC2 VPC Gateway Attachment
- EC2 Route Table
- EC2 Route
- 2 Public EC2 Subnets
- 2 EC2 SubnetRouteTableAssociations
- EC2 Security Group
Create ECS Repository
# registry (in the form $registryId.dkr.ecr.$region.amazonaws.com)
region=$(aws configure get region)
registryId=$(aws ecr describe-registry | jq -r '.registryId')
registry="$registryId.dkr.ecr.$region.amazonaws.com"
# repository
repository=$(aws ecr describe-repositories | jq -r ".repositories[] | select(.repositoryName==\"$image\") | .repositoryUri")
# create if it does not exist
[ -z "$repository" ] && aws ecr create-repository --repository-name $image
repository=$(aws ecr describe-repositories | jq -r ".repositories[] | select(.repositoryName==\"$image\") | .repositoryUri")
Create Docker image
Dockerfile
Create a Dockerfile
with the following contents:
cat << "EOT" > ./Dockerfile
# See https://hub.docker.com/_/oraclelinux for all supported
# Oracle Linux categories from Docker Hub.
# this image will be the actual running container
FROM oraclelinux:8
LABEL Name=ecs-test
## System Config
ENV TZ=America/Los_Angeles
# Packages
RUN yum -y install bind-utils
CMD ["/bin/ping", "localhost"]
EOT
Build Image
Tag Image
repository=$(aws ecr describe-repositories | jq -r ".repositories[] | select(.repositoryName==\"$image\") | .repositoryUri")
echo "Tag image ..."
docker tag ${image}:${tag} ${repository}:${tag}
Publish Image
# refresh AWS token for docker
aws ecr get-login-password --region $region \
| docker login --username AWS --password-stdin $registry
# push image
echo "Push image ..."
docker push ${repository}:${tag}
Verify
# verify
red='\e[0;31m'
green='\e[0;32m'
clear='\e[0m'
pushed_tag=$(reg categories ${repository} | grep "${tag}")
if [ "${pushed_tag}" != "${tag}" ]; then
printf "${red}Failed${clear}"; echo
else
printf "${green}Success${clear}"; echo
fi
Launch ECS Task
Service Description
Create docker-compose.yml
file:
cat << EOT > ./docker-compose.yml
version: '3'
services:
ecs-test:
image: $repository:$tag
logging:
driver: awslogs
options:
awslogs-group: test-ecs
awslogs-region: us-west-2
awslogs-stream-prefix: test
EOT
Task Definition
Create ecs-params.yml
file:
cat << EOT > ./ecs-params.yml
version: 1
task_definition:
services:
ecs-test:
cpu_shares: 100
mem_limit: 524288000
EOT
Launch Service
# create service
ecs-cli compose \
--project-name $service_name \
--file ./docker-compose.yml \
--ecs-params ./ecs-params.yml \
service up \
--create-log-groups \
--cluster-config test-ecs \
--ecs-profile swift
Login to the first task of the test
service:
CLUSTER=test-ecs
SERVICE=test
TASK_ARN=$( aws ecs list-tasks --cluster=$CLUSTER --service-name=$SERVICE | jq -r '.taskArns[0]' )
CONTAINER_INSTANCE_ARN=$( aws ecs describe-tasks --cluster=$CLUSTER --tasks $TASK_ARN | jq -r '.tasks[0].containerInstanceArn' )
EC2_INSTANCE=$( aws ecs describe-container-instances --cluster=$CLUSTER --container-instances $CONTAINER_INSTANCE_ARN | jq -r '.containerInstances[0].ec2InstanceId' )
EC2_IP=$( aws ec2 describe-instances --instance-ids $EC2_INSTANCE | jq -r '.Reservations[0].Instances[0].PublicIpAddress' )
EC2_KEY="~/.ssh/aws-ec2-key"
ssh -i $EC2_KEY ec2-user@$EC2_IP -t 'bash -c "docker exec -it $( docker ps -a -q -f name=ecs-'$SERVICE' | head -n 1 ) bash"'
Check task logs:
task_id=$( aws ecs list-tasks --cluster=test-ecs --service-name=test | jq -r '.taskArns[0]' | cut -d "/" -f 3 )
ecs-cli logs --task-id $task_id
Cleanup
WARNING: These scripts destroy the created AWS resources. Proceed with caution!!!
Stop services
Stop running tasks and remove service:
Delete cluster
Delete log group
Delete image
repo=ecs-test
registryId=$(aws ecr describe-registry | jq -r '.registryId')
aws ecr batch-delete-image \
--registry-id $registryId \
--repository-name $repo \
--image-ids imageTag=latest
Delete image repository
This will delete all images in the repo and the repo itself