---
# System prepended metadata

title: Deploy a secure and highly available Node.js application to EC2
tags: [Tag(change me!)]

---

# Deploy a secure and highly available Node.js application to EC2.

###### tags: `AWS`, `AutoScaling Group`, `ELB`, `Deployment`, `SSL`

> How to securely deploy a Node js application with Auto Scaling functionality and SSL. 
<!-- > Type on the left :arrow_left: and see the rendered result on the right. :arrow_right:  -->

## :Computer: Let's get started

### Step 0: Create a Node.js application 
#### Create a new github repo
![](https://hackmd.io/_uploads/r1gAo9jla.png)

![](https://hackmd.io/_uploads/r1Mg2qoeT.png)

#### Clone the repo to local
![](https://hackmd.io/_uploads/Hy1Zhqiea.png)


#### npm init and install express
![](https://hackmd.io/_uploads/SJjWhcjga.png)
![](https://hackmd.io/_uploads/SyeGhciga.png)

#### Add app.js file to your Node.js root directory with your favorite text editor
![](https://hackmd.io/_uploads/BywEn9ox6.png)

#### Push local changes to GitHub
![](https://hackmd.io/_uploads/ryOv2qjl6.png)

#### (Optional) Make sure it runs locally
![](https://hackmd.io/_uploads/rJWF35sxp.png)

![](https://hackmd.io/_uploads/rkbqh9slT.png)

:::info
:bulb: You can also clone this repo ➜ [Repo Link](https://github.com/tim61114/node-js-example) 
:::
### Step 0.5: Get Domain name and register on Route53
#### We'll first create a hosted zone for our domain name. I got my domain from name.com but I chose not to use their hosted service. 
![](https://hackmd.io/_uploads/Sk_CT6jg6.png)

#### Get the nameserver from Route53
![](https://hackmd.io/_uploads/r1nR6pse6.png)

#### Pass it to the name server from name.com 
![](https://hackmd.io/_uploads/BkkJCTigp.png)
:::info
:smile: Don't forget to save changes!
:::

### Step 1: Create SSL Certificate
We will then create an SSL certificate for our webpage. We create that using Amazon Certificate Manager with a registered domain name.  

#### Request a public certificate
![](https://hackmd.io/_uploads/B11oRajep.png)

#### Pass your domain name, validate with either DNS or Email
![](https://hackmd.io/_uploads/BJQiRaslT.png)

#### Wait till the request gets verified. 
![](https://hackmd.io/_uploads/r1Lj0Togp.png)

#### Verified!
![](https://hackmd.io/_uploads/rkeX10sxT.png)

:::info
:bulb: Be sure you create records in Route53. If not, click on the "create records in Route53"
:::

### Step 2: Create Security Group, Launch Template for our EC2

#### We'll create a security group for our Autoscaling Application before we create our EC2 VMs
The SSH is for accessing the VM, if you don't want that, just remove it.
The Custom TCP is for accessing the Node application.

![](https://hackmd.io/_uploads/Byq_zCjep.png)

#### Create Launch Template for our AutoScaling Group
![](https://hackmd.io/_uploads/Byj6zCila.png)

#### We'll be using the Amazon AMI for our EC2 Operating System
![](https://hackmd.io/_uploads/B1ukXRsx6.png)

#### Choose the Instance of your choice. I'm poor. Please don't judge
**Create a Key Pair is required if you want to Access your VM safely.**
**Choose the Security Group we previously created. Mine is called *Auto-Scaling-Nodejs-sg***
![](https://hackmd.io/_uploads/S1jkmAigT.png)

#### Setup user data in Advanced Section
**This allows us to put our code into the EC2 VMs when it starts.**
![](https://hackmd.io/_uploads/B1akQRol6.png)

Here's the code. Be sure you modify the git clone and cd command correctly.
```bash
#!/bin/bash -ex

exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
. /.nvm/nvm.sh

nvm install node
export NVM_DIR="/.nvm"	
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"	
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" 

sudo yum upgrade -y 
sudo yum install git -y

cd /home/ec2-user
git clone https://YOUR_REPO_HERE
cd YOUR_REPO_DIR_HERE
sudo chmod -R 755 .
npm install

node app.js > app.out.log 2> app.err.log < /dev/null &
```

### Step 3: Create Auto Scaling Group and Application Load Balancer
#### Choose the Launch Template we created in Step 2
![](https://hackmd.io/_uploads/SJZRBRjlT.png)

#### Choose Launch Options
**I created mine in the default VPC, with support in three Availability Zones**
![](https://hackmd.io/_uploads/Bk7RrCsxT.png)

#### Create a new Load Balancer (ALB in this case)
**We also create a target group at the same time at the bottom**
![](https://hackmd.io/_uploads/BkI0H0jg6.png)
![](https://hackmd.io/_uploads/S1KCHCsxT.png)
![](https://hackmd.io/_uploads/S1hCS0jx6.png)

#### Configure the size of your ASG. Mine is default 2, maximum 3
**The scaling policy checks the utilization of the CPU. You can use other metrics.**
![](https://hackmd.io/_uploads/S1CCrAsep.png)

#### The rest are optional. 

#### My EC2 VMs are now running. (Almost)
![](https://hackmd.io/_uploads/r1yAI0il6.png)

#### Accessing my EC2 VMs via port 3000 to check if it's working
![](https://hackmd.io/_uploads/SJKfvCjea.png)
![](https://hackmd.io/_uploads/HyRrwAsga.png)

#### Check my ALB. We'll check if this works as well
![](https://hackmd.io/_uploads/S1PKvRoeT.png)

#### Go to port 3000 of my ALB DNS. It works!
![](https://hackmd.io/_uploads/Sy3oPAog6.png)

### Step 4: Enable SSL certificate on my ALB

**This is the ALB I created in Step 3**
#### Click on Add listener under 'Listeners and rules'.
![](https://hackmd.io/_uploads/Sk18u0jeT.png)

#### Select Forward traffic to HTTPS 443 and forward to target group.
**We created the target group when creating the ALB**
**Choose the SSL certificate we created in Step 1**
![](https://hackmd.io/_uploads/ByWJ5Rixa.png)
![](https://hackmd.io/_uploads/B1mkq0ixa.png)

#### Now let's see if we can visit the Applciation using HTTPS.
**YES!**
(Although my browser is crying about this https certificate is not safe.)
![](https://hackmd.io/_uploads/S1oOQ13x6.png)

### Step 5: Add ALB URL to DNS

#### Head back to Route 53
![](https://hackmd.io/_uploads/rk-AiAsxa.png)

#### We'll create a new record. Click Create record
![](https://hackmd.io/_uploads/rJAAiRox6.png)

#### Create record using Alias. I specified a subdomain for my website but it's not required.

Pick Alias to Load Balancers, choose your region (Mine is US East 1), and Load Balancer.
![](https://hackmd.io/_uploads/ryyyZJhl6.png)

#### DONE
![](https://hackmd.io/_uploads/B1aLZJhlp.png)

Look at that, isn't that beautiful?

## Let's review what we did. 
1. We created a Node.js Application 
2. Setup a Domain name, update Namespace servers, and create hosted zones in Route 53
3. Create SSL certificate
4. Create Security group for our EC2 VMs and Launch Template
5. Create AutoScaling Group and Application Load Balancer
6. Enable SSL certificate on Application Load Balancer
7. Forward traffic from domain name to our ALB with SSL enabled.

**EZPZ right?**