Three-Tier Web Architecture in AWS

Overview

The 3-tier architecture is the most popular infrastructure pattern and consists of three layers, one public layer and two private layers. This architecture is used in a client-server application where the web application has a frontend, a backend, and a database. The public layer has a web tier, and the two private layers have an application tier and a database tier respectively. The public layer acts as a shield to the private layers. The public layer is publicly accessible, while the two private layers are only accessible within the network.

Web Tier: This public layer is also known as the presentation layer, consists of the web tier and is the topmost layer of the application that provides user interface and handles interaction with the user. The public layer is backed by an internet-facing Elastic Load Balancer that directs traffic to the application servers. In this project, we have provisioned one EC2 instance each in two availability zones. This will allow for high availability, and redundancy in case of a failure of an entire availability zone.

App Tier: This is also known as logic tier, contains a set of rules for processing information, business logic, and is able to accommodate many number of users. This is where our application servers live. The servers are wrapped in an auto scaling group for scalability and availability. App tier is backed by an internal Elastic Load Balancer which allows traffic arriving only from the instances placed in the public layer. It processes the inputs received from the clients and interacts with the database.

Database Tier: The third layer is the database layer where our databases live. Only the traffic coming from the application layer can connect to the databases. In this project, we have used Relational Database Management System (RDBMS) which manages and provides access to the data. It provides security, data integrity, and support to the application.

Architecture

Steps to create AWS 3-Tier Architecture

1. Network and Security

1.1 Create an S3 bucket in the us-east-1 region. This is where our code will be stored later which will be used to deploy the app

1.2 Create an IAM role for EC2 and attach SSMManagedInstanceCore, and S3ReadOnlyAccess permissions policies to it

1.3 Create an isolated network VPC with a CIDR range of 10.0.0.0/16, within which we will be building out the networking components like subnets, route tables, internet gateway, NAT gateway, and security groups

1.4 Create 6 subnets where 3 subnets are configured to be in one availability zone (us-east-1a), and the other 3 subnets to be in another availability zone (us-east-1b). Each subnet in one availability zone will correspond to each layer of our three-tier architecture

1.5 Create an Internet Gateway and attach it to the VPC, so that the public subnets will have access to the internet

1.6 In order to provide internet access to the app instances in private subnets, create two NAT Gateways and deploy one in each public subnet in each availability zone for high availability

1.7 Create a public route table for the public web subnets and add internet gateway in the routes, so that the IPs outside of the VPC’s CIDR range will be routed to the internet gateway. In addition to that, explicitly associate both the public subnets with the route table

1.8 Create 2 more route tables for the app layer private subnets that are in 2 availability zones. These route tables will route traffic destined for outside VPC to the NAT gateway in the corresponding availability zone. For that, edit routes, add NAT gateway and associate the corresponding private app subnet and repeat the same for another private app subnet in another availability zone

1.9 Create 5 security groups

1.9.1 First security group is for the public, internet facing load balancer with an inbound rule that allows HTTP traffic for "My IP"

1.9.2 Second security group is for the public instances in the web tier, add HTTP inbound rule to allow internet facing load balancer security group that is created previously and also add a rule to allow HTTP traffic from "My IP"

1.9.3 Third security group is created for the internal load balancer with an inbound rule that allows HTTP traffic from the web tier security group. This allows traffic from the web instances to hit the internal load balancer

1.9.4 Fourth security group is created to allow traffic from the internal load balancer to hit the private app instances. For this, add inbound rule with internal load balancer security group created before and for TCP port 4000 to allow "My IP" as well

1.9.5 Fifth security group is for the private database instances. Add an inbound rule with private app instances security group to MySQL/Aurora port 3306

2. Database Deployment

2.1 Create a database subnet group with VPC we created and add the private subnets that were created for the database layer in two availability zones

2.2 Create a database, configure with MySQL compatible Amazon Aurora as the database engine, in a dev/test environment. Set up a username and password which will be used later to access the database. Select the option to create an Aurora Replica or reader node in a different availability zone for high availability and durability. After the database is provisioned, writer instance and reader instance are created in different availability zones

3. App Tier Instance Deployment

3.1 Launch an EC2 instance for the private app tier, configure with Amazon Linux, t2 micro, VPC, private app subnet in one of the availability zones, and with security group created for private app tier attached. Also select IAM EC2 role we have created in the very first step

3.2 Connect to the instance using Session Manager and verify if we are able to ping the google DNS servers. The packets should start transmitting if the network is configured correctly

3.3 Install MySQL server on the app instance, and connect to the DB instance by using Aurora RDS writer endpoint, user name and password which we should have noted while creating the database. Create a table in the database and insert some data into it which will later be used in testing

3.4 Configure the writer instance endpoint, username, password, and the database name in DBConfig.js file and upload the app-tier folder to the S3 bucket

3.5 Using the commands shown on the workshop documentation, install all the necessary softwares, dependencies etc to run our app successfully even when we close the SSM session or in case the server is interrupted for any reasons

3.6 To test if the app layer is configured correctly, run health checks to see if the app is running and is able to connect to the database. The app layer is configured correctly if the items in the database table are displayed

4. Internal Load Balancing & Auto Scaling

4.1 Create an Amazon Machine Image from the app tier instance

4.2 Create a target group which will be used with the load balancer to balance traffic between the private app tier instances

4.3 Create an internal load balancer for which we will use Application Load Balancer that listens to HTTP port 80, forwarding the traffic to the target group

4.4 Create a launch template by using the AMI created earlier, with appropriate security group and IAM EC2 role attached

4.5 Create an Auto Scaling Group using the launch template and associate this with the load balancer created earlier. Set the minimum capacity, desired capacity and maximum capacity to 2

4.6 If everything is configured correctly, Auto Scaling Group should provision two new instances since we set our desired capacity to 2

5. Web Tier Instance Deployment

5.1 Update the nginx configuration file provided as part of AWS workshop with the internal load balancers’ DNS name, and upload this file and the web tier folder to the S3 bucket created initially

5.2 Launch a web tier instance similar to that of app tier instance’s configuration but this time launch web instance in a public web subnet and with web tier security group, IAM role. Also, enable auto-assign public-IP

5.3 Connect to the instance and test by using ping 8.8.8.8 and if the configuration is working correctly, packets should start transmitting which means everything seems to be working well

5.4 After making sure the configuration is correct, install some required components on the web instance to run the front-end application. Download the web-tier code from the S3 bucket, run build, install nginx and configure to serve our application on port 80 and help send API calls to the internal load balancer

5.5 After the configuration is complete, using the public IP of the web tier instance, we should now be able to see the web app and the connected database as well

6. External Load Balancing & Auto Scaling

6.1 Create an Amazon Machine Image from the web tier instance

6.2 Create a target group which will be used with the load balancer to balance traffic across the web tier instances

6.3 Create an internet facing load balancer for which we will use Application Load Balancer that listens to HTTP port 80, forwarding the traffic to the target group

6.4 Create a launch template by using the AMI created earlier, with appropriate security group and IAM EC2 role attached. Create an Auto Scaling Group using the launch template and associate this with the load balancer created earlier. Set the minimum capacity, desired capacity and maximum capacity to 2

6.5 If everything is configured correctly, Auto Scaling Group should provision two new instances since we set our desired capacity to 2

6.6 Finally, with the help of load balancer DNS name, we should be able to land on the AWS 3-Tier Web App Demo page as shown below

Note: All the required code, commands to install packages, softwares, dependencies, builds are all available from the AWS Workshop Studio (refer to the link above).