Quick jump:
- 1. Tutorial overview
- 2. Creating the Cluster
- 3. Creating the ALB
- 4. Creating the Task Definition
- 5. Creating the Service
- 6. Testing our service deployments from the console and the ALB
This tutorial will guide you through the creation of an ECS Cluster and the deployment of the container with a simple application created in the previous lab.
In order to run this tutorial, you must have completed the following steps:
Once you've signed into your AWS account, navigate to the ECS console. This URL will redirect you to the ECS interface on N. Virginia region. If this is your fist time using ECS, you will see the Clusters screen without any clusters in it:
Let's create our first ECS Cluster. Click in the button Create cluster, select the EC2 Linux + Networking cluster template and click in Next Step
:
You will then be asked to input information about your new cluster. In the Configure cluster screen, keep the default values to the fields, changing just these ones:
- Cluster name:
containers-workshop-ecs-cluster
- EC2 instance type:
t2.micro
- VPC: Select the VPC
containers-workshop-vpc
created in the 01-Setup Environments step - Subnets: Select the
containers-workshop-private-subnet-az1
andcontainers-workshop-private-subnet-az2
subnets in your VPC
And then click in Create.
In this tutorial we are not covering the creation of a Key Pair to access your EC2 instances. If you want to access your instances for troubleshooting purposes or even to just see how the ECS agent works you will need to create a Key Pair and then select it in the
Key pair
option. You can see how to create a new Key Pair in this link.
Note that this wizard is also going to create a security group for you allowing access in the port 80 (TCP).
After changing all these parameters and putting the needed information, click in the button Create in the end of the screen.
When the creation process finishes, you will see the following screen:
You can then click in the button View Cluster to see your cluster. The ECS Cluster screen will be like this:
Now that we've created our cluster, we need an Application Load Balancer (ALB) to route traffic to our endpoints. Compared to a traditional load balancer, an ALB lets you direct traffic between different endpoints. In our example, we'll use the enpoint /app
.
To create the ALB:
Navigate to the EC2 Service Console, and select Load Balancers from the left-hand menu. Click in Create Load Balancer. Inside the Application Load Balancer
, click in Create:
Name your ALB containers-workshop-alb
and add an HTTP listener on port 80:
In this same screen, under Availability Zones select the VPC containers-workshop-vpc
previously created and select the two public subnets:
After adding the information about your Availability Zones, click in Next: Configure Security Settings.
When clicking in next, you should see a message saying that your load balancer is not using any secure listener. We can just skip this screen, clicking in Next: Configure Security Groups.
NOTE: In a production environment, you should also have a secure listener on port 443. This will require an SSL certificate, which can be obtained from AWS Certificate Manager, or from your registrar/any CA. For the purposes of this workshop, we will only create the insecure HTTP listener. DO NOT RUN THIS IN PRODUCTION.
Let's now create a security group to be used by your ALB. In the Step 3: Configure Security Groups screen, let's select the option Create a new security group
. Change the Security group name to containers-workshop-alb-sg
and create a rule allowing all traffic in the port 80
:
Them, click in Next: Configure Routing.
During this initial setup, we're just adding a dummy health check on /
. We'll add specific health checks for our ECS service endpoint when registering it with the ALB. Let's change only the the Name to dummy
:
Click in Next: Register Targets and then in Next: Review. If your values look correct, click Create:
After creating your ALB, you need to update the security group rule so your ALB can access the EC2 instances where your containers will run. In order to identify what is the security group applied to your instances, you can access the ECS console, select the cluster containers-workshop-ecs-cluster
and then select the tab ECS Instances. You will see that you have one instance running. Then, click in the ECS Instance ID:
NOTE: in this screen, you will find two different ID's. One of them is related to the
Container Instance
, which will show you all the tasks running in this specific instance as well as some data from the EC2 Instance. The other ID is theEC2 Instance
ID, that will redirect you to the EC2 console, where you can manage the EC2 instance.
In the EC2 service dashboard, you will see all the information about your instance. In this screen, click in the security group name. This name is going to be similar to EC2ContainerService-containers-workshop-ecs-cluster-EcsSecurityGroup-12SD646C23L1H:
In this screen, with the Security Group selected, click in the tab Inbound and then in Edit. Here, we will have a rule previously create allowing traffic in the port 80 from anywhere. Let's change this rule, in order to allow all traffic coming from the ALB security group to our EC2 instance. Start changing the Type
to All Traffic
and in the field Source
start typing sg-
. You will see a list with all the security groups created in your AWS account. Select the security group containers-workshop-alb-sg
previously created and click in Save:
The final rules in your instance Security Group should look like this:
At this point, your EC2 instances will be able to receive traffic from the ALB.
NOTE: When creating this rule we are allowing all the traffic from the ALB to the instances. We are doing that because when working with ECS we can use a dynamic port mapping feature in order to run more containers with the same image in the same EC2 instance, so when starting our task, we will not specify any port to run our application and the ECS will do it for us. Since we don't know what is the port that the Docker daemon will expose, we need to allow all traffic to have our application accessible by the ALB.
When working with ECS to run our applications, there are a few concepts that we need to understand. The first of these concepts is about what is a Task
. Basically, a task is a subset of containers that we need to execute in order to have our application running. The Tasks
are defined in a configuration called Task Definition
.
A Task Definition
is where you will specify your task. Things like the Docker Image version, the amount of CPU and memory that each container will need, what ports needs to be mapped, data volumes, environment variables and other informations are going to be specified in the Task Definition.
The first thing that we will need, is the information about the image that we want to use. In this case, we are going to use the image created in the Creating Your Docker Image tutorial. To get the image URI, navigate to the ECR page and click in Repositories
. You will see the repository named containers-workshop-app
. In this screen, you will also see that there is a Repository URI
. Take note of this URI:
To create a Task Definition, in the ECS Page click in the Task Definitions
menu, and then click in Create new Task Definition. Select EC2 as the Launch type compatibility and click in Next step:
Let's add now the information about this task definition. Name your task containers-workshop-ecs-task-def
and under Task Role select None
:
In the Task execution IAM role select Create new role
and under Task size add 128
in the Task memory (MiB) field:
NOTE: If this is not your first ECS Cluster, you should already have an IAM Role created. In this case, you should select the previously created IAM Role.
The next step is to add the information about our container. Click in the Add container button, under Container Definitions. The name of the container will be containers-workshop-app
. In the Image field, add the URI that you got before, pointing to your image.
Under Port mappings add 0
in the Host port field and 80
in the Container port.
A few things to note here:
-
We've specified a specific container image, including the
:latest
tag. Although it's not important for this demo, in a production environment where you were creating Task Definitions programmatically from a CI/CD pipeline, Task Definitions could include a specific SHA, or a more accurate tag. -
Under Port Mappings, we've specified a Container Port (80), but left Host Port as 0. This was intentional, and is used to facilitate dynamic port allocation. This means that we don't need to map the Container Port to a specific Host Port in our Container Definition - instead, we can let the ALB dynamically allocate a port during the task placement. To learn more about port allocation, check out the ECS documentation here.
Once you've specified your Port Mappings, scroll down and add a log driver. There are a few options here, but for this demo, select Auto-configure CloudWatch Logs:
Once you've added your log driver, click in Add to add the container in your task definition, and finally click in Create in the Task Definition
screen.
Now that we have the description of everything we need to run our application in the Task Definition
, the next step is to run our container using Amazon ECS. Let's do it by creating a Service
.
In ECS, a Service
allows you to run and maintain a specified number (the "desired count") of instances of a task definition simultaneously in an Amazon ECS cluster. If any of your tasks should fail or stop for any reason, the Amazon ECS service scheduler launches another instance of your task definition to replace it and maintain the desired count of tasks in the service. You can find more information about ECS Services in the ECS documentation.
Navigate back to the Clusters screen on the ECS console, and click in the cluster name containers-workshop-ecs-cluster
previously created.
If you don't have a cluster named containers-workshop-ecs-cluster, create one following the procedures in Creating the cluster.
In the details page of the containers-workshop-ecs-cluster , click in the button Create, in the Services
tab:
Select EC2
as the Launch Type
, and choose the Task Definition created in the previous section. For the purposes of this demo, we'll only start one copy of this task.
In a production environment, you will always want more than one copy of each task running for reliability and availability.
Name your service containers-workshop-ecs-service
.
You can keep the default AZ Balanced Spread for the Task Placement Policy. To learn more about the different Task Placement Policies, see the documentation, or this blog post.
Click in Next.
Under Service discovery (optional) uncheck Enable service discovery integration.
Now, under Load balancing
, select Application Load Balancer
. Let's configure the integration between the ECS Service and the Application Load Balancer, so we will be able to access the application using the ALB. Select Create new role
under Service IAM role
and underContainer to load balance
, select the container containers-workshop-app:0:80
. Click in Add to load balancer:
This final step allows you to configure the container with the ALB. When we created our ALB, we only added a listener for HTTP:80. Select this from the dropdown as the value for Listener. For Target Group Name, enter a value that will make sense to you later, like containers-workshop-ecs-target
. For Path Pattern, the value should be /*
. In the Evaluation order, add the number 1
.
Finally, Health check path, use the value /
.
If the values look correct, click Next Step.
Since we will not use Auto Scaling in this tutorial, in the Set Auto Scaling
screen, just click in Next Step and after reviewing your configurations, click in Create Service.
You can see service level events from the ECS console. This includes deployment events. You can see if your service was deployed and registered properly with the ALB by looking at the service's Events tab:
We can also test from the ALB itself. To find the DNS A record for your ALB, navigate to the EC2 Console > Load Balancers > Select your Load Balancer. Under Description, you can find details about your ALB, including a section for DNS Name. Enter this value in your browser:
You can see that the ALB routes traffic appropriately based on the path (/
) we specified when we registered the container