Auto deploy and auto scale servers: using AWS CodeDeploy and GitHub Actions

Ansu K
4 min readJan 11, 2022

When you push your code to the repository, as a developer, you have to take an extra step to deploy the latest code to the running servers. When there is a high load on your current servers, you have to spin up new instances and deploy the latest code to it manually.

To avoid this human dependency for scaling infrastructure and keeping the severs up to date, there is a need for a pipeline that can do it all for you.

For creating such a pipeline, I have used AWS CodeDeploy to create deployments, Github Actions to auto deploy the latest code by invoking AWS CodeDeploy and AWS Auto Scaling Group to auto scale our infrastructure. We’ll learn how each of the service works below.

Let’s first understand the status quo of our infrastructure layout.

Current Setup

Let’s assume we have a few production servers, a few staging servers and a couple utility servers all running on AWS EC2 Instances.

The production servers are running the actual application and a few worker tasks in the interest of decoupling the compute functions. The staging servers are a mirror of production servers for testing the application before releasing to production.

Utility servers are the ones which do not contain the application code but aid in running the backend servers like a load balancer, a bastion server or a db server. Here, we won’t make any changes to the utility servers because our code is not deployed on them and although they can create a bottleneck for backend servers, which can cause issue while scaling, we’ll cross that bridge when we come to it.

Now, in order to deploy the latest code on any of the backend servers you need to ssh into the instance and do a git pull; which, depending on the number of servers you have, can take anywhere from 5 minutes to 5 hours. Further, if load on your server increases you will manually need to add more EC2 instances and git pull your latest code to it or create an AMI with the latest code and launch instances with it. These steps can again take hours and would be a very slow process.

The solution to the above problem is in automating manual labour.

ASG — Auto Scaling Group

ASG is a group of ec2 instances responsible for the following:

  • Check health of each instance present in the group.
  • Maintain desired capacity (configurable metrics) of healthy instances.
  • Spin up more instances if the average load on the instances increase the set capacity, up to the maximum provided instance capacity. For eg, if the average CPU utilization is > 50% it’ll launch a new instance to maintain the average CPU utilization.
  • Terminate instances to maintain desired capacity is average load decreases.

In our proposed setup, we will create an ASG for the server and each worker for both production and statging. So, for instance, if we have three worker jobs running we will create four ASG for production — one for running application (eg, npm start), three for running each worker job.

Similarly, we will have four staging ASGs. That is, a total of eight ASGs running homogeneous EC2 instances.

AWS CodeDeploy

AWS CodeDeploy consists of three components — Applications, Deployment Groups and Deployments. We do not need to go into the details of each component so we will only focus on Deployments as of now.

For the sake of simplicity, we can consider a Deployment Group being equivalent to an ASG. We will create eight Deployment Groups and assign an ASG to each and give them the same name as the ASG.

A Deployment can be considered as a function that takes in a few parameters and performs a certain task. It takes in (1)commit ID, (2)Deployment Group Name and (3)script: on how to run the server after code push. Once a deployment is created with the required inputs, it pushes the code from the commit ID to the instances present in the ASG and then runs the script to start the server/worker job.

GitHub Pipeline

Github pipeline is a yml script that fetches the commit ID that needs to be pushed on the server on the specified trigger action, like code push or tag creation, and creates a Deployment with that commit ID.

--

--