How to Create Infrastructure for a Node.js Application on AWS

A guide on how to set up the infrastructure for a Node.js application on AWS.

Shishir Khandelwal
AWS in Plain English

--

Deploying a scalable web app on EC2s along with setting up access to it using a load balancer is a good project to pursue to learn about cloud and aws.

In this article, a very simple Node.js application will be used to show the various steps required for its infrastructure setup.

Aim of This Guide:

  • Create a launch configuration for deploying a simple NodeJS application on EC2s.
  • Understand user-data script to deploy the application.
  • Start an Auto Scaling Group to easily scale the application.
  • Look into target group & load balancer creation to serve traffic over the multiple EC2s.

Creating a Launch Configuration

Launch configurations are definitions of the servers we wish to deploy, they contain details like the following:

  • The operating system the server is going to run on.
  • The type of instance e.g. t2.micro, m5.large, etc.
  • Security settings of the servers.

We are going to work with the following settings:

  • Ubuntu AMI
  • t2.micro for 1 GB of RAM and 1v CPU.
  • A minimum of 8GB EBS is required while launching the EC2 — let’s keep it as a minimum.

In the next step of adding detailed configurations to our launch configuration, we need to specify the user data script of the EC2.

Creating the User-Data Script for the EC2

  • We are going to use a simple NodeJS application I created.
  • Ubuntu requires npm and node installed for running the application — so these components must be installed.
sudo apt update -y
sudo apt install nodejs -y
sudo apt install npm -y
  • The NodeJS application code can be pulled from my GitHub repository — It has the necessary npm module files present already.
mkdir -p /home/ubuntu/.ssh
ssh-keyscan -t rsa github.com > /home/ubuntu/.ssh/known_hosts
git clone https://github.com/shishirkh/nodejs-webapp.git
  • Next, the application requires an env var IP_ADDRESS defined. To do that — the value must be specified in the env file. You can go over the index.js file to understand it better!
ip_addr=$(cat /etc/hostname)
echo $ip_addr
sed -i 's/IP_ADDRESS_PLACEHOLDER/'"$ip_addr"'/g' env
  • Finally, we need to set up the pm2 npm package — PM2 is a production process manager for NodeJS applications. PM2 enables us to keep applications alive forever and reloads them without downtime.
  • We are going to start the application and keep it running by running the pm2 commands from the user data script. We’ll also configure pm2 to start our application again if the ec2 gets rebooted.
sudo npm install pm2@latest -g
sudo pm2 start index.js
sudo pm2 startup
sudo pm2 save
  • This is the full script that can be used -
#!/bin/bashcd /home/ubuntu/
sudo apt update -y
sudo apt install nodejs -y
sudo apt install npm -y
mkdir -p /home/ubuntu/.ssh
ssh-keyscan -t rsa github.com > /home/ubuntu/.ssh/known_hosts
git clone https://github.com/shishirkh/nodejs-webapp.git
cd nodejs-webapp
ip_addr=$(cat /etc/hostname)
echo $ip_addr
sed -i 's/IP_ADDRESS_PLACEHOLDER/'"$ip_addr"'/g' env
sudo npm install pm2@latest -g
sudo pm2 start index.js
sudo pm2 startup
sudo pm2 save

That’s all the work required for the user data script!

  • Inside the security group settings for the launch configuration — we need to open access to port 3000 since the NodeJS application has been configured to run on port 3000 by default.
    This can be changed from the env file.

That’s all the work required for launch configurations.

Creating the Auto-Scaling Group

  • From the launch configurations UI — create an auto-scaling group.
  • I am going to name my auto-scaling group “webapp-as”.
  • For the network setup, I am going to use the default AWS VPC and Public Subnets.

Configuring the Load Balancer

  • Since we want to access the multiple EC2s created via the auto-scaling group on which the application is going to run — a load balancer is required.
  • A load balancer automatically distributes the incoming traffic across multiple targets, such as EC2 instances. It also monitors the health of its registered targets and routes traffic only to the healthy targets.
  • We want to create an internet-facing load balancer so that we can access it from anywhere.
  • Inside the listener section, we want to keep it as port 80 because we want to access the load balancer on port 80 and the load balancer will then redirect the request to one of the server’s port 80. This means we may have to change the redirect the target port to 3000 afterward.
  • You can also set this port as 3000 and then change the listener port of the load balancer to 80. In this way, the load balancer will listen to port 80 and redirect the requests to port 3000 of the servers.
  • For now, let’s keep the desired no. of servers that the auto-scaling group will create as 2.
  • Notifications & Tags can be skipped.

That’s all the work required for the auto-scaling group.

Testing the Application

  • After the auto-scaling group’s instances become available — you can try to access the application via the browser by using this address -
http://[public ip addr of ec2]:3000
  • Notice that the application displays the hostname of the ec2 as well. This will be helpful when we access the application from behind the load balancer.

Configuring the Health Checks of the Load Balancer

  • Since our application is running on port 3000, the health checks of the load balancer must be configured on this port. If this is not set correctly, then you’ll see that the load balancer health checks are failing for all the servers.
  • This is how you can correctly configure the load balancer health checks i.e. overriding it to use port 3000.
  • After that, the health checks will become successful.
  • Since the load balancer health checks have passed now, the application will be accessible through the load balancer DNS as well.
  • If you keep refreshing the page with the load balancer DNS — you’ll see that requests are being served by different ec2 servers. This shows that the requests are being load balanced correctly
  • NOTE: If you get a timeout or gateway errors, check the security group settings of your load balancer. Ideally, it should have ports 80 open for access over HTTP protocol & port 443 open for access over HTTPS protocol.
0

That’s all folks! Hope this was useful and clear.

Share your feedback and follow me on Linkedin for more!

More content at plainenglish.io

--

--

I spend my day learning AWS, Kubernetes & Cloud Native tools. Nights on LinkedIn & Medium. Work: Engineering @ PayPal.