Create infrastructure to host an Amazon ECS Service using Terraform

This is the first part of an umbrella note in which I describe how to create and deploy an Amazon ECS service using Terraform and GitHub Actions.

The cloud engineering team must provision particular AWS cloud services before hosting a container in Amazon ECS. In this note, I list all the required AWS services, their specific properties, and how to create them using Terraform.

Per AWS-Docs, Amazon ECS is a fully managed container orchestration service that helps you easily deploy, manage and scale containerized applications. It hosts one or more Docker images as container(s) in an Amazon ECS Cluster as one or more tasks or services. Per AWS-Docs, an Amazon ECS cluster is a logical grouping of tasks or services. It requires a VPC where the tasks and services run. These tasks or services are created from a task definition. The task definition also contains the metadata about the task/service, such as the number of containers, port-mapping, memory, the environment variables, and the Docker image source, which, in our case, is Amazon ECR. Amazon ECR is a managed AWS Docker registry service that stores images. You may find more information at AWS-Docs.

Architecture Decision
Depending on your use case, you may provision more AWS cloud services. In my case, I attached a load balancer to the Amazon ECS service and, hence, required that along with a target group and listener. Since this was an external-facing load balancer, I hosted that in (public) subnets attached to a route table with a route to 0.0.0.0/0 (the internet) using the internet gateway. I was required to create the Amazon ECS service in private subnets to make the architecture secure. A private subnet is a subnet that is not attached to a route table with a route to 0.0.0.0/0 (the internet). The Amazon ECS service requires access to Amazon ECR and Amazon S3 to pull the Docker image layers and Amazon CloudWatch for container logging. Hence, to access these from the private subnet, I created VPC endpoints to Amazon ECR, S3, and CloudWatch, along with the private subnet’s route table changes. If I were required to host the Amazon ECS service in a public subnet and assign a public IP address to the service, these VPC endpoints would not be necessary since Amazon ECS could access these services via the internet gateway.

Tying all of these together, you will notice that all these specific AWS cloud services can exist before a service is hosted on Amazon ECS. These are Amazon VPC, subnets, route tables, internet gateway, security group, VPC endpoints, an Amazon ECS cluster, Amazon ECR, a load balancer, a target group, and a listener. At a secondary level, there are additional AWS services like AWS KMS Key and Amazon CloudWatch log group to encrypt the data and store the logs.

I will list these AWS cloud resources and show you how to create them using Terraform. I also list the specific properties of these AWS cloud services and why they are necessary. If you want to follow along, here is a link to my GitHub repository and folder to access the Terraform code: kunduso/add-aws-ecr-ecs-fargate/infra. I also automated the process using GitHub Actions pipeline which you may access at: terraform.yml.

Step 1: Create AWS KMS key and policy
The AWS KMS key encrypts the data stored in the Amazon CloudWatch logs and the Docker image stored in the Amazon ECR repository. By encrypting the data we ensure that only those with the key can access them.
90-image-2

Step 2: Create an Amazon CloudWatch log group
The log group stores messages from the Amazon ECS service. These messages are log information, which is helpful during review and debugging.
90-image-3

Step 3: Create the network components
The network components include the Amazon VPC, public and private subnets, route tables, routes, and internet gateway. These resources are standard; however, I set two VPC properties to true. You can read them at AWS-Docs: Setting Up DNS in Your VPC.
90-image-4
If interested, you can read more about Amazon VPC, subnets, route tables, route table associations, internet gateway, and routes in a route table at  – create Amazon EC2 using Terraform.

Step 4: Create security groups and rules
Two security groups are required for this use case: one to enable traffic flow to the load balancer and the other for the VPC endpoints. The ports and CIDRs are different for both security groups. For ease of management, I created separate security group rules rather than inline rules with the security group.
90-image-9

Step 5: Create VPC endpoints
This use case requires four VPC endpoints: two ECR interface endpoints, one CloudWatch interface endpoint, and one Gateway endpoint for Amazon S3. Along with creating the VPC endpoints, I attached the VPC endpoint security group with the three interface endpoints and a private subnet route table association to the Gateway endpoint for Amazon S3.
90-image-8
Step 6: Create an Amazon ECR repository
An Amazon ECR repository is where the (Docker) container images are stored.
90-image-5
The image_tag_mutability property states whether the same image tag can be reused. Setting it to IMMUTABLE = same image tag cannot be reused.

Step 7: Create an Amazon ECS Cluster
An Amazon ECS cluster is a logical grouping of tasks or services to be created before hosting them. While creating the ECS cluster, I enabled and added the logging configuration to direct the task or service logs to the Amazon CloudWatch log group.
90-image-6

Step 8: Create the load balancer, target group, and listener
I created an Amazon ECS service with a couple of tasks that served a static page and placed a load balancer in front to toggle traffic between the two tasks. Hence, I required a load balancer, target group, and listener.
90-image-7
For a detailed explanation of the load balancer, target group, and listener, refer to my previous note  –add an application load balancer to Amazon EC2 using Terraform.

That brings us to the end of this note. Once all these AWS cloud resources are provisioned, developers can start developing containerized applications and storing the Docker image in Amazon ECR.

One thought on “Create infrastructure to host an Amazon ECS Service using Terraform

Leave a comment