Deploying Docker Image on AWS ECS, Infrastructure Automation using Terraform: A Step-by-Step Guide with Code
Introduction
Amazon Elastic Container Service (ECS) is a fully-managed container orchestration service provided by Amazon Web Services (AWS). It enables you to easily run, scale, and manage Docker containers in the cloud. In this blog post, we will explore how to deploy a Docker image on AWS ECS using Terraform, an infrastructure automation tool.
Prerequisites
Before we dive into the step-by-step guide, there are a few prerequisites you need to fulfill:
An AWS account with sufficient permissions to create ECS resources
Docker installed on your local machine
Basic understanding of Docker and ECS
Step 1: Create an ECS Cluster
The first step is to create an ECS cluster. Follow these steps:
- Create a new file named “main.tf” and add the following code:
provider "aws" {
region = "us-west-2"
}
resource "aws_ecs_cluster" "my_cluster" {
name = "my-ecs-cluster"
}
This code creates an ECS cluster named “my-ecs-cluster” in the US West (Oregon) region.
2. Initialize the Terraform working directory by running the command “terraform init” in the directory where your “main.tf” file is located.
3. Apply the Terraform configuration by running the command “terraform apply”. Terraform will prompt you to confirm the creation of the resources. Enter “yes” to proceed.
Step 2: Create an ECR Repository
Next, we need to create an Elastic Container Registry (ECR) repository to store our Docker image. Follow these steps:
- Add the following code to your “main.tf” file:
resource "aws_ecr_repository" "my_ecr_repository" {
name = "my-ecr-repo"
}
This code creates an ECR repository named “my-ecr-repo”.
2. Apply the Terraform configuration by running the command “terraform apply”. Enter “yes” to confirm the creation of the resources.
Step 3: Build and Push the Docker Image
Now, we need to build our Docker image and push it to the ECR repository. Follow these steps:
- Create a new file named “Dockerfile” in your project directory and add the following code:
FROM node:12
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]
This Dockerfile specifies that we want to use the Node.js 12 image as the base, installs our dependencies, exposes port 3000, and runs the command “npm start”.
2. Build the Docker image by running the command “docker build -t my-ecr-repo .”. This command builds the Docker image using the current directory as the build context and tags it with the name of the ECR repository.
3. Login to the ECR repository by running the command “aws ecr get-login-password | docker login — username AWS — password-stdin ACCOUNT_ID.dkr.ecr.us-west-2.amazonaws.com”. Replace “ACCOUNT_ID” with your AWS account ID and “us-west-2” with the AWS region where you created the ECR repository
4. Push the Docker image to the ECR repository by running the command “docker push ACCOUNT_ID.dkr.ecr.us-west-2.amazonaws.com/my-ecr-r..”. Replace “ACCOUNT_ID” with your AWS account ID and “us-west-2” with the AWS region where you created the ECR repository.
Step 4: Create an ECS Task Definition
Now that we have built and pushed our Docker image to ECR, we need to create an ECS task definition that specifies how to run our Docker container. Follow these steps:
- Add the following code to your “main.tf” file:
resource "aws_ecs_task_definition" "my_task_definition" {
family = "my-task-def"
container_definitions = jsonencode([{
name = "my-container"
image = "${aws_ecr_repository.my_ecr_repository.repository_url}:latest"
essential = true
portMappings = [{
containerPort = 3000
hostPort = 0
protocol = "tcp"
}]
}])
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = "256"
memory = "512"
}
This code creates an ECS task definition named “my-task-def” that specifies how to run our Docker container. It pulls the latest version of our Docker image from the ECR repository, exposes port 3000 and specifies the Fargate launch type.
2. Apply the Terraform configuration by running the command “terraform apply”. Enter “yes” to confirm the creation of the resources.
Step 5: Create an Application Load Balancer
Next, we need to create an Application Load Balancer (ALB) to route traffic to our ECS task. Follow these steps:
- Add the following code to your “main.tf” file:
resource "aws_security_group" "alb_security_group" {
name_prefix = "alb-sg"
vpc_id = aws_vpc.default.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0"
]
}
}
resource "aws_lb" "alb" {
name = "my-alb"
internal = false
load_balancer_type = "application"
security_groups = [
aws_security_group.alb_security_group.id
]
subnets = aws_subnet.private.*.id
}
resource "aws_lb_listener" "alb_listener" {
load_balancer_arn = aws_lb.alb.arn
port = "80"
protocol = "HTTP"
default_action {
target_group_arn = aws_lb_target_group.target_group.arn
type = "forward"
}
}
resource "aws_lb_target_group" "target_group" {
name_prefix = "my-target-group"
port = 3000
protocol = "HTTP"
vpc_id = aws_vpc.default.id
target_type = "ip"
health_check {
interval = 30
timeout = 10
healthy_threshold = 3
unhealthy_threshold = 3
path = "/"
matcher = "200-399"
}
}
This code creates an ALB, a security group for the ALB, a listener, and a target group. The ALB is associated with the security group and the listener is configured to forward traffic to the target group on port 3000.
2. Apply the Terraform configuration by running the command “terraform apply”. Enter “yes” to confirm the creation of the resources.
Step 6: Register ECS Task with the Target Group
Finally, we need to register our ECS task with the target group so that it can receive traffic from the ALB. Follow these steps:
- Add the following code to the “main.tf” file:
resource "aws_lb_target_group_attachment" "target_group_attachment" {
target_group_arn = aws_lb_target_group.target_group.arn
target_id = aws_ecs_task_definition.my_task_definition.task_definition_arn
port = 3000
}
This code registers our ECS task with the target group created in the previous step.
2. Apply the Terraform configuration by running the command “terraform apply”. Enter “yes” to confirm the creation of the resources.
Once the resources have been created, you can go to the AWS Management Console and verify that the ECS cluster, task definition, ALB, listener, target group, and target group attachment have been created successfully.
To deploy a new version of the application, you can simply update the Docker image in the ECR repository and then update the task definition to use the new image. Terraform will automatically update the ECS task and register it with the target group. This allows for easy and efficient deployment of new versions of the application.
In conclusion, deploying a Docker image on AWS ECS and automating the infrastructure using Terraform can be a powerful way to manage your application. With Terraform, you can easily define and manage your infrastructure as code, which enables reproducibility, version control, and automation. By following the steps outlined in this article, you can deploy your Docker image on ECS, automate your infrastructure and enable efficient deployment of new versions of your application.