In this article, let’s deploy a sample Docker-based web application on AWS EC2 using Auto Scaling Group. But, why Auto Scaling Group? Because our application should be scalable. The ASG will take care of the horizontal scaling during situations like higher CPU utilization, unhealthy application instances, etc. The setup will reduce service downtime and scale the application during high-traffic surges. I’ll make this deployment pipeline as simple as possible so, you can understand the concepts clearly. So, let’s deep dive into the deployment of a Docker application using ASG and ELB.
Auto Scaling Groups and their Benefits
- Auto-scaling groups (ASG) automatically replace unhealthy instances and distribute traffic across healthy instances, improving the overall availability of your application.
- By scaling the number of instances based on the demand, you can optimize costs by avoiding over-provisioning and only paying for the resources you use.
- With auto-scaling, you can ensure that your application can handle fluctuations in traffic without degradation in performance, providing a seamless experience for users.
Prerequisites
In order to deploy our scalable web application on AWS, we will use the following components:
- EC2 & Launch Templates
- Security Groups
- Auto Scaling Group (ASG)
- Elastic Load Balancer (ELB)
- Target Groups
- Docker
Steps
Here’s the top-level overview that how we can scale our application using AWS AutoScalingGroup:
- Step 1: At first, will create a Security Group for Application Load Balancer that allows inbound traffic at port 80
- Step 2: Then, we will create an EC2 Launch Template with attached the Security Group we have created. The template will contain infra settings for our EC2 instances including the ‘User data’ that will install Docker & pull our sample Docker image during instance creation.
- Step 3: Create a Target Group with Instances target type
- Step 4: Then, we will create an Application Load Balancer attached to the Target Group.
- Step 5: In this step, create an AutoScalingGroup (ASG) using the Launch Template we have created. The Load Banacer will be attached to the AutoScalingGroup.
- Step 6: Finally, will check our application using the Load Balancer URL.
- Step 7 (Optional): Edit the Security Group of EC2 Instances/ Launch Template and attach the Load Balancer’s Security Group with the inbound traffic rule.
At this point, I gave you the basic overview of the architecture we will follow to deploy our scalable applicable. Now, it’s time to get our hands dirty with the application deployment using AutoScalingGroup.
Step 1: Create a Security Group for Load Balancer
The Security Group in AWS, associated with EC2, is a component that creates a network firewall to control inbound and outbound traffic. For our sample express application, we have to ensure that the service will only be available on port 80. So, let’s create a Security Group that only allows inbound requests through port 80.
- Sign in to the AWS Management Console
- Visit the EC2 service and set the region. We will select ‘ap-south-1’ for this project.
- Go to Security Groups from the Network & Security and Click on ‘Create security group‘
- Give the following details:
- Security group name
- Description
- VPC: You can select the default VPC or can attach a new VPC.
- Add an Inbound rule for port 80 with the following details:
- Type: Custom TCP
- Protocol: TCP
- Port range: 80
- Source: Anywhere IPv4
- Add an Outbound rule for all traffic. The outbound rule will allow our EC2 instances to install application dependencies including Docker.
- Type: All Traffic
- Protocol: All
- Port range: All
- Source: Anywhere IPv4
- Now, click on the ‘Create Security Group’ button
Step 2: Let’s Create the EC2 Launch Template
The Launch Template provides functionality for EC2 auto-scaling. In the Launch Template, we will set the computing unit for our application. Also, will set a bash script as ‘User data’ that will install Docker and run our docker application on port 80.
- Sign in to the AWS Management Console
- Visit the EC2 service and set the region. We will select ‘ap-south-1’ for this project.
- Click on the ‘Create Launch Template’ button from the left menu item ‘Launch Templates’
- Give template name & description
- Select Ubuntu from the ‘Application and OS Images‘ and choose the OS version from the AMI option
- Select the Instance type of t2-micro
- Select or Create a Key pair (optional)
- From the Network settings, create a new Security Group that allows inbound traffic to TCP port 80. Please note. it’s not mandatory to allow port 80 for EC2 instances. For the sake of simplicity & testing the application using Insance’s IP address we are allowing port 80. Later we can remove this rule as well (mentioned in step number 7).
- In the ‘Advanced Details‘ section set the following User data. The script will install Docker and run our Docker Express application on port 80 during the EC2 instance launch.
#!/bin/bash
sudo apt-get update -y
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo systemctl restart docker
sudo docker run -p 80:3000 prodocker21/hello-express:1.0.7
- Finally, click on the Create launch template button
Step 3: Create a Target Group with Instances target type
Target Groups are used to route requests to one or more registered target instances (Eg. EC2 instances). In our application, we will set targets as EC2 instances. Let’s create the Target Group for our Load Balancer.
- Sign in to the AWS Management Console
- Visit the EC2 service and set the region. We will select ‘ap-south-1’ for this project.
- Click on the ‘Create Target Group’ button from the left menu item ‘Target Groups’
- Select Target Type as Instances
- Give a name for the Target Group
- Set IPv4 Network Protocol
- The default ‘/’ health check endpoint is fine for our application. Set HTTP/ HTTPs for Health Check Protocol
- In this step, we will skip registering the EC2 instances into the target group. This will be done by AutoScalingGroup.
- Click on the Create Target Group to create the Target Group
Step 4: Create the Application Load Balancer
A Load Balancer acts as a single endpoint for clients. The primary responsibility of a typical Load Balancer is to distribute incoming application traffic across multiple targets, such as EC2 instances and multiple Availability Zones. In our application, we will use Application Load Balancer to distribute traffic across EC2 instances created by AutoScalingGroup. Here’s how:
- Sign in to the AWS Management Console
- Visit the EC2 service and set the region. We will select ‘ap-south-1’ for this project.
- Click on the ‘Create Load Balancer’ button from the left menu item ‘Load Balancers’
- Select Application Load Balancer and click on the Create button
- Give a Load Balancer Name
- Select Internet-Facing Scheme as our application will be public and available via HTTP protocol
- Choose IPv4 or Dualstack from the IP address type option
- Select the VPC and availability zones
- Attach the Security Group we have created
- Set the Target Group with Port 80 we created in the previous step
- Leave the other settings as default and click on the Create load balancer button to create the load balancer
- Note the Load Balancer Endpoint or the DNS Name for Application testing
Step 5: Let’s Create the Auto Scaling Group (ASG)
An Auto Scaling Group contains a group of EC2 instances. The primary role of ASG is to spin up new instances based on certain conditions (Eg. health check, unavailability of EC2 instances, etc.).
- Sign in to the AWS Management Console
- Visit the EC2 service and set the region. We will select ‘ap-south-1’ for this project.
- Click on the ‘Create Auto Scaling Group’ button from the left menu item ‘Load Auto Scaling Group‘
- Give a name
- Set the Launch Template that we have created in step number 2
- Select the VPC, same as our ALB, and Availability Zones and subnets
- Attach our Load Balancer to the Target Group
- Set the Health Check Grace Period to 20 seconds (optional)
- Set the Desired Capacity under Group Size. (Eg. 2. Means the target group spins up at least 2 EC2 instances )
- Set Min Desired Capacity (Eg. 2) & Max Desired Capacity (Eg. 4)
- Configure Auto Scaling policy (Optional)
- Select Target Tracking Scaling Policy
- We will leave the default settings
- Finally, click on the Create Auto Scaling Group. Once you create the ASG, it will launch EC2 instances automatically.
Step 6: Test the WebApp
As soon as you create the Target Group, it will spin up EC2 instances. You can check those from Instances or Target Groups.
EC2 instances will take a few minutes to up and running. During instance creation all dependencies will be installed for our application. Once, the Health status gets Healthy, you can test the application using the Load Balancer URL. Your application should be up & running. And your application is now distributed across EC2 instances.
Congregations, we have deployed our scalable web application using AWS AutoScalingGroup. The application will ensure the following:
- The application will always be available for at least 2 EC2 instances.
- In case of unavailability of any EC2 instance, ASG will spin up a new EC2 instance which will be available through the ALB.
- Also, ASG will spin up a new EC2 instance in case the CPU usage of existing EC2 instances exceeds the benchmark. At any time we can update the ‘Min Desired Capacity‘ & ‘Max Desired Capacity‘ units from our AutoScalingGroup.
Step 7: Securing EC2 Instances from Public Access (Optional)
We have already deployed our web application using ASG. However, you can still use the application using EC2 public IP. And this is not a best practice. We have to ensure that our application is accessible only via the load balancer URL. Now let’s do this
- Go to Security Groups under EC2 & open the group that is attached to our Launch Template/ EC2 instances
- Click on Edit Inbound Rules and attach only the security group that we created for our load balancer in step number 1. This will restrict public access to our EC2 instances.
- Click on Save Rule
Conclusion
Amazon EC2 Auto Scaling Groups provide a flexible and efficient solution for scaling your applications on AWS. By automating the process of adding and removing instances based on demand, you can ensure that your application maintains optimal performance while minimizing costs. By following best practices and leveraging the capabilities of auto-scaling groups, you can build scalable and resilient applications that can handle dynamic workloads with ease.