A step by step ECS tutorial
This post provides a step by step tutorial to get started with ECS, i.e Elastic Container Service.
Your application might want to perform some resource consuming task every once in a while.
An example would be sending an SMS or an Email to a select group of users.
You might not want to execute this task on the application server since it would consume the application server’s resources.
This task of sending SMS or Emails can be easily accomplished on an ECS setup.
We want to keep this post agnostic of any language or framework. We also want to keep the setup as simple as possible.
Thus our tasks consists of a simple and minimal shell script which would be deployed on ECS.
The major components we would be discussing are:
- ECR i.e Elastic Container Registry
- ECR Repository
- ECS Task Definition
- ECS Cluster
- ECS Task
To complete this tutorial, following prerequisites are expected.
- AWS Account
- AWS CLI setup
- Docker setup
As ECS is an AWS Service, hence we can only see it in action in a working AWS account.
As the name Elastic Container Service suggests, ECS works with respect to containerised applications.
Any containerised application needs to have an image, and the relevant image needs to be present on a registry.
ECS works in tandem with the container registry provided by AWS. This registry is called Elastic Container Registry i.e ECR.
To publish or push an image from your local machine to ECR, you would need the Amazon CLI. You should have the CLI setup correctly.
To setup CLI, check the relevant documentation.
To verify proper working of AWS CLI, issue the following command
$ aws --version
In the above command, $ is the command prompt. The actual command is
The container image needs to be built on the local machine. Hence a functioning docker setup is required.
To verify proper working of Docker, issue the following command
$ docker --help
Let’s write a shell script which writes “Winter is coming!” to the standard output.
Create a directory and navigate to it.
$ mkdir echo-script
$ cd echo-script
Create a script.sh file.
$ vim script.sh
Add the following content to this file.
echo Winter is coming!
Change the permission of this file to make it executable.
$ chmod u+x script.sh
Confirm it’s working as intended by executing it.
You would notice “Winter is coming!” being written to the standard output.
Containerise the script
As ECS always works in the context of a container, hence we need to containerise the script.
Create a file named Dockerfile in the current directory, i.e in echo-script.
$ vim Dockerfile
Add the following content to it.
ADD script.sh /srv
CMD ["/bin/bash", "script.sh"]
With the Dockerfile added, let’s build an image for this application.
$ docker build -t echo-script .
Hence, we have created a Docker image with name/repository echo-script.
Let’s verify that we are able to run a Docker container using this image.
$ docker run --name echo-container echo-script
You would notice “Winter is coming!” being written to the standard output. This confirms that our script is containerised and the image and container are working as intended.
Feel free to remove the stopped container.
$ docker rm echo-container
For ECS to be able to use the Docker image, the image needs to be hosted on a registry.
We will use ECR as our registry. A repository needs to be created on ECR, before the image can be pushed.
Navigate to AWS service Elastic Container Registry.
Click on Create repository which would take you to a form.
Enter the Repository name as echo-script.
Let the other fields stay as they are and do not change them.
You would be redirected back to the list page and you would start seeing repository echo-script in the list.
Click on the repository name to visit the details page. It would look like the following.
You would notice that currently there are no images in this repository.
Click on View push commands, this would tell the steps needed to push the image from your local machine to ECR repository.
Let’s execute these commands to push the image to ECR repository.
$ aws ecr get-login-password --region ap-south-1 | docker login --username AWS --password-stdin 117635876922.dkr.ecr.ap-south-1.amazonaws.com
My AWS account ID is 117635876922, that’s why the registry URL I see is 117635876922.dkr.ecr.ap-south-1.amazonaws.com.
Your registry URL would differ based on your AWS account id.
Once the above command is executed, you would see message Login Succeeded.
We can skip step 2 since we have already built the image locally.
As per step 3, let’s tag the local image, this will allow us to push the image to the ECR repository.
$ docker tag echo-script:latest 117635876922.dkr.ecr.ap-south-1.amazonaws.com/echo-script:latest
Again, use your AWS account ID here.
Let’s push the tagged image to the ECR repository.
$ docker push 117635876922.dkr.ecr.ap-south-1.amazonaws.com/echo-script:latest
Refresh the repository detail page. You would start seeing an image with Image tag as latest.
ECS creates tasks based on task definition. Task definition are templates based on which tasks are created.
A task is essentially an instance of a task definition.
The major components of a task definition are:
- Task definition family name
- Container image
- Container name
- App environment
Navigate to service Elastic Container Service.
Toggle on New ECS Experience at the top left of the page.
Navigate to Task Definitions. You would find it in the left side navigation.
Click on Create new task definition.
The form would take you through 3 steps.
Step 1 is Configure task definition and containers.
Let’s enter Task definition family as echo.
A task definition definitely needs atleast one container information. In Container-1, fill the following details:
- Name: echo-container
- Image URI: 117635876922.dkr.ecr.ap-south-1.amazonaws.com/echo-script:latest
You would find Essential Container set as Yes. Let Private registry authentication be toggled off.
We don’t want to map any port of the container with a port on the host. Hence remove the Port mappings.
You would find a button called + Add more containers. A task definition can have multiple containers.
We will only have a single container in our task definition, so ignore this button.
Click on Next to navigate to Step 2.
Step 2 is Configure environment, storage, monitoring, and tags
We want our script to be executed on a serverless setup. We don’t want to provision an EC2 instance.
Most likely you would see App environment as AWS Fargate (serverless). Do not change this.
Similarly, there is no need to change the Operating system/Architecture.
Our script doesn’t need too much of computing resource or memory. Hence, modify the Task size to select the lowest possible configuration, i.e CPU to .25vCPU and Memory to .5 GB.
There is no need to change anything in section Container size.
In Task execution Role, click on Create new role.
We are instructing ECS to run our script on Fargate. Thus a Fargate instance would be provisioned by ECS and the image needs to be pulled on this instance.
This can only be done if Fargate instance has appropriate IAM role and attached policy to pull the image. Hence ECS needs a Task Execution Role which it will associate with the Fargate instance.
There is no need to change anything in section Storage. Similarly, there is no need to change anything in section Monitoring and logging.
Ensure that Use log collection is checked. However, it should be checked by default and no change should be needed here.
Click on Next to navigate to Step 3.
Review the relevant sections.
Click on Create.
You would land on Task definition detail page.
We need a cluster to run an ECS task.
Navigate to Clusters section. You would find it in the Left side navigation.
Click on Create cluster.
In the create cluster form, provide a Cluster name. We are naming our cluster as sloth.
Every other section i.e Networking, Infrastructure, Monitoring and Tags can be left as it is.
Click on Create.
You would land on Cluster list page. Navigate to the cluster detail page.
Switch from Services to Tasks tab on the Cluster detail page.
As evident from this page, this cluster has 0 Running tasks. If you switch from Running tasks to Stopped tasks, it would still show 0 since no task has been run yet in this cluster.
Click on Run new task. You would start seeing the Create form.
Under Compute options, switch from Capacity provider strategy to Launch type.
Select the Task definition Family as echo. This is the task definition we created in the previous section.
Click on Create.
You would be navigated back to the Cluster detail page. You would notice a Tasks launched notification.
Click on the Task hyperlink to navigate to Task detail page.
There is not much work to be performed in this task, hence it would have stopped soon after being run.
The task detail page would look similar to the following.
By default, you would be on the Configuration tab. Swith to the Logs tab.
We can see the message “Winter is coming!” here.
This confirms that our application was executed on a Fargate serverless instance.
We were able to get an application executed without provisioning and managing any server.
This application was extremely simple. Your application can be highly complex, however as long as it can be containerised, it can run extremely well and smooth on ECS.
We only touched the tip of the iceberg. ECS is much more capable and powerful at provisioning, management and orchestration. It has numerous other use cases where it can shine.
Stay tuned for more posts on ECS!