Hands-on: Configuring a 3-tier autoscaling service with NGINX Reverse Proxy AWS.
Tags: aws, vpc, cloud, tutorial
Published: 2022-12-29 14:37:14

In this article, I have described step by step process(s) by which to configure a AWS cloud solution for a company having 2 websites with a reverse proxy technology.

**Use case**: To build a secure infrastructure inside AWS VPC network for a company that uses WordPress CMS for its main business website, and a Tooling Website for their DevOps team. As part of the company’s desire for improved security and performance, a decision has been made to use a reverse proxy technology from NGINX to achieve this. Cost, Security, and Scalability are the major requirements for this project.

In this project, you will gain understanding and configure some AWS resources like VPC, Security groups, Auto Scaling groups, Target groups, Lunch Templates and much more by implementing the architecture diagram below.

![infrasture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i8a1qhvbkc939y35utnf.png)

This implementation have been divided into five major categories. As such, this tutorial is divided into five series as well to make it simple and easier to follow.

**Prerequisites** 
- An AWS account [AWS free tier](https://aws.amazon.com/free/)
- Some Knowledge of Linux command
- A Domain name (Your can get a free domain from [Freenom](https://www.freenom.com/en/index.html?lang=en))

_Let's Get Started!!!_

## Reverse Proxy
A reverse proxy is the application that sits in front of back-end applications/servers and forwards client requests to those applications. Reverse proxies help increase scalability, performance, resilience and security. The resources returned to the client appear as if they originated from the web server itself.

## NETWORKING
As with constructing a building, the foundation is always very important and that brings us to VPC. From the diagram above, you would see that the VPC is the backbone of the whole infrastructure. By the way, VPC means Virtual Private Cloud.

Amazon Virtual Private Cloud (Amazon VPC) enables you to provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you've defined. This means most AWS resources would need VPC to communicate between each other except for a _severless_ architecture [read more](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html)

### Create a VPC
Login into your AWS account and search for VPC in the search bar
![search vpc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f8piud2oag5339qivyo9.png)
Click on Create VPC.

![Create VPC](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8q0bheftz9i0qfgi9p62.png) _Note: as shown in the above diagram, every account comes with a default VPC_

```bash
# Let's create our VPC with these information below
- Set Resources to create to VPC only
- Set Name to any name of your choice
- Set IPv4 CIDR to 10.0.0.0/16

Leave the other options and click on create VPC
```

![vpc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hsuz1s7ln7t13qd24yor.png)

Next, we will configure the following are AWS resources that  the VPC needs to provide the connectivity that our applications requires -  Subnets, Route tables, Internet gateways, Elastic IPs, NAT gateways, Security groups.

### Create Subnets
Subnets are simply groupings of IP addresses. A subnet is a range of IP addresses in your VPC. You can launch AWS resources into a specified subnet. Use a public subnet for resources that must be connected to the internet, and a private subnet for resources that won't be connected to the internet directly.

In the infrastructure diagram above, we need two public subnets (for the nginx reverse proxy and bastion server) and 4 private subnets (for the web servers and database). My region is set to US East (Northern Virginia) Region and I have decided to use two availabity zones(AZs) for this project namely us-east-1a and us-east-1b.

Still on the VPC dashboard, click on subnets

![subnet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hc4ex1lhbxu6pprr21a.png)

Click on create subnet
![subnets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jwc3pgtoq7jxfkwdkicp.png) _Note: The default the VPC comes other default features like default subnets, internet gateway, route tables etc._

```bash
# Create two Public Subnets
Set VPC ID to your newly create VPC
Set Subnet name to your preferred name
Set Availability Zone to us-east-1a
Set IPv4 CIDR block to 10.0.1.0/24
```
![public1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6hn8a9awgdusoy4auk0.png)
Create the second public subnet in Availability Zone us-east-1b and set IPv4 CIDR block to 10.0.3.0/24 as seen the diagram.

![Public subnet2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/48xxutvtffl5v2e747xl.png)

> _You can configure all 6 subnets on the same page by clicking `add new subnets` before you finally click on the `create subnet button`._

```bash
# Create 4 Private Subnets
Set Private subnet 1 in us-east-1a with IPv4 CIDR block 10.0.2.0/24
Set Private subnet 2 in us-east-1b with IPv4 CIDR block 10.0.4.0/24
Set Private subnet 3 in us-east-1a with IPv4 CIDR block 10.0.5.0/24
Set Private subnet 4 in us-east-1b with IPv4 CIDR block 10.0.6.0/24
```

![subnets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4nd5unfieuw86lqzh89j.png)


### Create Internet Gateway
The VPC needs a way to communicate with the internet to allow client communication, to do this we need to configure a internet gateway. An internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows communication between a VPC and the internet.

Still on the VPC dashboard, click on internet gateways in the left menu and Click on Create Internet gateway
![Igw](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n5zwktd1lrhrfqh8mxk5.png)

- Enter a name for the internet gateway
- Click on create internet gateway

![Internetg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3msm66iqlori4594wps7.png)

- Next click on _Attach to VPC_ on the top right of the page or click on _Actions_
- Select the your VPC and _click attach Internet gateway_

![attached](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/recy2kwl2wt17gpb85su.png)

### Create Elastic IP
We need an Elastic IP address as a requirement to configure the NAT gateway. The need would become clearer soon. An Elastic IP address is a static, public IPv4 address designed for dynamic cloud computing.

- Click on Elastic Ips in on left menu for the VPC dashboard
- Click on _Allocate Elastic IP address_
- Enter a tag Name and click on _Allocate_

![elastic ip](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfmi4o0ni6z16efoy4nj.png)

### Create Nat Gateway
As seen in the infrastructure diagram above, the web servers and the data layer are placed in the private subnets, meaning that they don't have direct access from or to the internet which ensures security. However, under AWS shared responsibility for IaaS, it is our responsibility to manage patches and updates to the AWS resources we provision (for EC2 instance we used). Hence, we need to way for the EC2 instances to communicate with the internet to download patches. A NAT gateway enable us to do just that.

A NAT gateway is a Network Address Translation (NAT) service. it does not allow any inbound traffic from the internet but allows outbound traffic from the private subnets associated with it.

- Click on _Nat gateways_ on left menu of the VPC dashboard
- Click _Create NAT gateway_
- Enter a Name 
- Select a Public Subnet under _Subnet_
- Connectivity type - Public
- Elastic IP allocation ID - click the dropdown arrow to select the Elastic IP we just created
- Create NAT gateway

![NAT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hp5yds62iw22hxqt2xu8.png)

### Create Route table
A route table contains a set of rules, called routes, that determine where network traffic from the subnets or gateway is directed. For the infrastructure diagram above, we need one private route table for the four private subnets and one public route table for the two public subnets.

Create Private Route Table
- Click route tables on the left menu on the VPC dashboard
- Click _create route table_
- Enter your preferred Name
- Select your VPC from the dropdown
- Click create route table

![private](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwd5o3u6p755t3rsljo2.png)
Repeat above steps to create the public route table.

![Public](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3bp6pd1xlwfjtvu6xbp.png)
Next, we need to associate the public subnet with the public route table and private subnet with the private route table.

Subnet Association with Route Table
- Select the the Public route table
- Click Actions on the top right of the route table dashboard
- Click on Edit Subnet associations

![rtb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6q42xmhmxtnk7pa18g8.png)
- Select the two public subnets
- Click save associations

![associations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qzxnme04k2yjpxe2fa7.png)
Repeat the steps above to associate the private subnets with the private route table. Make sure your select the four private subnets only.

![all](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jusxgv8nbr80egdlpdfx.png)

Edit Routes for Route Tables
Now, we need to add the routes for communication in the route tables. For the Public route table, the internet gateway as the target and anywhere IP CIDR would be the destination. For the private route, the Nat gateway would be the target and anywhere IP.

- Select the the Public route table
- Click in Actions on the top right of the route table dashboard
- Click on Edit routes

![routes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01mqc44krnqoi5fy2zal.png)
- Click on Add route
- Destination - 0.0.0.0/0
- Target - internet gateway
- Click save changes

![routes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ylt07ltqazhwgxrcumtm.png)

For the Private Route
Repeat the steps above but for Target choose the Nat gateway you created.

![routes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7z6dhp99rfq6e71pok4.png)

### Create Security Groups
Next, we will create the security groups needed for the AWS resources. A security group controls the inbound and outbound traffic from or to a AWS resource. To ensure the security of your infrastructure, it is important to allow only appropriate traffic from verified origin [read more](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html).

As seen in the infrastructure diagram above, we will need six security groups for :- 

_**External Load Balancer**_ - _should accepts all https(port 443) & https(port 80) inbound request from the browser._

- Click on Security Groups on the VPC dashboard
- Click on create security group
- Enter **`Name`**, **`description`** and select the appropriate **`VPC`**
- click on **`Add rules`** under **`inbound rules`**
- Select `HTTP` on port `80` and `HTTPS` on port `443` and `IPV4 Anywhere IP (0.0.0.0/0)` a the source
- Enter a Name tag
- Click **`create security group`**

![external alb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y83m3xo9zqhtdkqimtui.png)

_**Bastion Servers**_ - _should allow only SSH. The Bastion server will server as a jump server into any other instance/ server on the infrastructure for maintenance or troubleshooting purpose._

- Add Name, tag and description as above
- Add inbound rule as `SSH`
- Click **`create security group`**
![bastion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf3vg0dcgxwqmpl611u2.png)

**_Nginx Servers_** - _should accepts only inbound traffic from the external load balancer and bastion server._

- Add Name, tag and description as above
- Add inbound rules `HTTPS`, `HTTP` and select `external load balancer security group` as the source.

![nginx](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osqcr8hwux6fr2xpu7s0.png)

**_Internal Load Balancer_** - _should allow only inbound rules from the nginx proxy server._

- Add Name, tag and description as above
- Add inbound rules `HTTPS`, `HTTP` and select `Nginx reserve proxy security group` as the source.

![internal ALB](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2g1r4tiyc9bqg4wo8gtx.png)

**_Webservers_** - _should allow inbound rules from the internal load balancer and bastion server._

- Add Name, tag and description as above
- Add inbound rules `HTTPS`, `HTTP` and select `Internal load balancer security group` as the source.
- Add inbound rule `SSH` and source as bastion security group

![webserver sg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4c1g0nn8l2iqy15265vk.png)

**_Data Layer_** - _should allow inbound rules from the webserver and administrative access for the bastion server._

- Add Name, tag and description as above
- Add inbound rules **`MySQL/Aurora`** and select **`bastion security group`** as the source.
- Add inbound rules **`MySQL/Aurora`** and select **`webserver security group`** as the source.
- Add inbound rules **`NFS`** and select **`webserver security group`** as the source.

![Data layer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ykvvikpv5j2fml9y09z6.png)
Don't worry everything would become clearer as we move on.

Next, we will configure and setup Amazon RDS for database, Amazon EFS for file storage, generate our database encryption key in AWS KMS and generate SSL certificate in AWS Certificate Manager.

As always, I look forward to getting your thoughts on this  feature. Please feel free to leave a comment or click on the  subscribe button for more updates.