How to Create a Highly Available 3-Tier Architecture

Chanel
Nerd For Tech
Published in
13 min readJan 12, 2023
3-Tier Architecture

In a three-tier architecture, applications are organized into three logical and physical computing tiers where each tier runs on its own infrastructure.

The Web Tier or Presentation layer is where the user access your application using the frontend. It serves the purpose of displaying and gathering information from the user and is usually ran on a web browser. Think about it as using Amazon.com to order products.

The next layer is the Application tier which is where the information that was collected from the web tier is now processed. This layer is typically created with Java, Python, PHP or another coding language and it then interacts with the data tier using API calls. Think of this layer as once you go to checkout on Amazon.com, it has to verify card information, product availability, your address information, and other various steps on the backend.

The last layer is the Database Tier where the information processed by the application layer is stored and managed in either a relational database management system or a NoSQL database server.

In this tutorial I will show you step by step how to design and create a highly available 3-tier architecture with a web tier, application tier and a database tier.

Step 1: Create a Web Tier

In the web tier we’re going to create…

  • 2 Public Subnets with 2 EC2 Instances in an autoscaling group.
  • EC2 web server security group allowing inbound permission from the internet.
  • Create a custom AMI that includes a static web page.
  • Create a public route table and associate the 2 public subnets.

First we are going to create a VPC in the AWS management console. Simply search “VPC” in the search bar and click “Your VPCs” then click “Create VPC”. We will use the CIDR block 10.0.0.0/16 and then leave everything else default. In the lower right hand corner click “Create VPC”.

Creating the VPC

Go to the “Actions” tab and click on “Edit VPC settings” and within that check the box to enable DNS Hostnames and click “save”.

Enable DNS Hostnames

Next we are going to create our subnets. From the same screen on the left hand side under Your VPCs click “Subnets” then “Create Subnet”.

Under VPC ID make sure to select the VPC you created to associate the subnets with. In this step we are going to create the subnets for the web tier, application tier, and database tier so that will be 2 public subnets and 4 private subnets. We will use the following information for each subnet.

  • Public-1A: us-east-1a > 10.0.1.0/24
  • Public-1B: us-east-1b > 10.0.2.0/24
  • Private-1A: us-east-1a > 10.0.3.0/24
  • Private-1B: us-east-1b > 10.0.4.0/24
  • Private-1C: us-east-1c > 10.0.5.0/24
  • Private-1D: us-east-1d > 10.0.6.0/24

To create them all at the same time fill out the information for the first subnet and scroll to the bottom and click “Add new subnet”.

Finally after entering the information for the 6 subnets, click “Create subnet” in the lower right hand corner. You should get a message that you’ve successfully created your subnets.

Subnet Creation

For both of the public subnets select them and then click on the “Actions” dropdown and then “Edit subnet settings” and check the box “enable auto-assign public IPv4 address”.

Now we need to create an Internet Gateway so that our resources in the subnets will be able to reach the internet. Click “Internet Gateways” on the left hand side and then select “Create Internet Gateway”.

Simply name the Internet Gateway and click “Create internet gateway”. After creation, a notification will pop up to attach to VPC. Attach the Internet Gateway to the VPC you created earlier.

Now we are going to click on “Route Tables” and we can see we have a route table that was create when we created our VPC. We are going to edit the name first and label it “MAIN” route table. This will be the route table associated with our Public subnets.

Name Route Table

Click on the Route table ID and then click “edit routes”.

Click “Add route” and choose 0.0.0.0/0 and select Internet Gateway and the IGW you create will populate. Choose it and click “save changes”.

Add Route for Internet Gateway

We also need to associate the public route table with the public subnets. To the right of the Routes tab select “Subnet Associations”. In the heading “Explicit subnet associations” click “edit subnet association” on the right and select the 2 Public subnets and click “Save association”.

Associate Public subnets with Main Route Table

Next we are going to create an auto scaling group and to do that we are going to create a launch template first. In the EC2 dashboard under Instances select “Launch Templates” then click the orange button “Create Launch Template

Leave all settings default and change the following:

  1. Launch Template name: Your Template Name
  2. Application and OS Images (Amazon Machine Image): Quick Start > Amazon Linux
  3. Instance type: t2.micro (free tier eligible)
  4. Key Pair: Generate a new key pair (RSA/.pem)
  5. Network Settings: Create a Security Group by attaching your VPC and adding inbound rules as follows…
Firewall Settings
Security Group Settings
Security Group Settings continued

Then under the Advanced network configuration enable auto-assign public IP.

Advanced network configuration

6. Advance Details > User Data:

#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
EC2AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
echo '<center><h1>This Amazon EC2 instance is located in Availability Zone: AZID </h1></center>' > /var/www/html/index.txt
sed "s/AZID/$EC2AZ/" /var/www/html/index.txt > /var/www/html/index.html

7. Click orange “Create launch template

On the EC2 dashboard we are going to select “Auto Scaling Groups” all the way on the bottom on the left side and then click the orange “Create Auto Scaling Group”. Name your auto scaling group, select the template you just made and click “next”.

The default network may be selected so make sure to select your VPC and then select the 2 public subnets we created earlier and click “next”.

Select the 2 Public Subnets

For the next screen leave everything default and click “next”.

We are going to have a minimum of 2 EC2 Instances at all times and we will just set the max that it will scale to as 5.

Group size & Scaling Policy

Click next until you reach the last page which is the review page and click “Create Auto Scaling group” and you should get a confirmation page and if you check the EC2 dashboard you will see that we have 2 instances provisioned because that was the minimum number we wanted.

Our instance state is showing as running and our status check is in the green as well but you can grab the public IP’s from each instance just to make sure the information populates correctly.

Instance Running Successfully

Step 2: Create an Application Tier

In the application tier we’re going to create…

  • 2 Private Subnets with 2 EC2 Instances in an autoscaling group.
  • EC2 application server security group allowing inbound permission from the Web Server Security Group.
  • Associate with the private route table.

In our first step we already created the 2 private subnets that we need for the application tier but since they’re private subnets we still have to create a private route table and a NAT gateway for them.

Navigate to the VPC dashboard and click on “NAT gateways” and click “Create NAT Gateway”. Give your NAT Gateway a name and then choose a PUBLIC subnet to associate the NAT gateway with. The NAT Gateway gives internet access to private subnets but it MUST BE placed in a public subnet.

Last click “Allocate Elastic IP” and then “Create NAT Gateway”.

Next on the left hand side click on “Route tables” then click “Create Route table”. Just name the route table and select the VPC you created and then select “create route table”.

We are going to edit the route to associate it with the NAT gateway.

Click “Add route” and choose 0.0.0.0/0 and select NAT Gateway and the NAT gateway you create will populate. Choose it and click “save changes”.

Select NAT Gateway

Just like we did for the main route table, we are going to edit the subnet association of this private route table and we are going to associate it with the private subnets for the Application Tier then click “save associations”.

Select the 2 App Tier Private Subnets

Next we will create a launch template for the Application Tier. Navigate to the EC2 Dashboard and click “Launch Templates” and then “Create Launch Template”.

Leave all settings default and change the following:

  1. Launch Template name: Your Template Name
  2. Application and OS Images (Amazon Machine Image): Quick Start > Amazon Linux
  3. Instance type: t2.micro (free tier eligible)
  4. Key Pair: You can use the same key pair (RSA/.pem)
  5. Network Settings: Create a Security Group by attaching your VPC and adding inbound rules as follows…
***The “ping” utility uses ICMP request & reply***

6. Advance Details > User Data:

#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
EC2AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
echo '<center><h1>This Amazon EC2 instance is located in Availability Zone: AZID </h1></center>' > /var/www/html/index.txt
sed "s/AZID/$EC2AZ/" /var/www/html/index.txt > /var/www/html/index.html

7. Click orange “Create launch template

Back on the EC2 dashboard we are now going to create an auto scaling group for the Application Server. Choose a name for and select the application server launch template then click “next”.

Select the VPC and the 2 app tier private subnets and then select “next”.

Configure the group size and scaling policies as follows and click next until you reach the end and click “Create Auto Scaling Group”.

On the EC2 dashboard we can see that our auto scaling group is spinning up two more instances that I just went ahead and labeled for the sake of organization.

Step 3: Create a Database Tier

In the database tier we’re going to…

  • Create 2 Private Subnets.
  • Associate with private route table.
  • Utilize MySQL RDS Database.
  • The Database security group should allow inbound traffic for MySQL from the Application Server Security Group.
  • Create 1 RDS Instance.

We already created the private subnets for the database tier but we do need to associate the private subnets with the private route table. In the VPC dashboard click “Route tables” and click on the “Route table ID”. Edit the subnet associations and add the 2 database private subnets and save.

Now in the search bar we are going to search “RDS” and then click “Create Database”. Leave Standard create and select MySQL as the engine option.

For template, change to free tier. Under Credential Settings create a master password and confirm the password.

Change the Instance configuration to db.t2.micro.

  • Storage: Uncheck enable storage autoscaling
  • Connectivity: Virtual private cloud (VPC) > (Select your VPC)
  • VPC Security Group(firewall): Create new > Choose a name and an availability zone that one of the private database subnets are in.

Then click “Create Database”. It will take some time to create so we will exercise patience here. As the database is creating we are going to go back and update the inbound permissions on our application tier now that we have created the database.

Go the EC2 Dashboard, click Instances, Select the box for one of the app tiers, select the security tab and then select the security group. Once you click that click “Edit inbound rules”.

What you’re searching for is the name of the database security group you just created. You may get an error when trying to edit but just simply delete and add it again and then click “Save rules

Update MySQL/Aurora inbound rule

Now we are going to log into our web tier using our computers terminal. Go to the EC2 Dashboard and select a web tier to SSH into.

Successful SSH into Web Tier

Now that we are logged into the web tier we want to verify that we can ping the Application tier. We will do that by using the ping command on the private IP off the application tier. Yours will not be the same as mine but go to the EC2 dashboard and retrieve the private IP from one of the application tier instances.

#this will be your own private IP address
ping 10.0.3.168

This is what it should look like. It will keep pinging unless you stop it so use “control C” just to get out of the ping command.

Successful Ping

Lastly we want to make sure that we can connect to our Application tier. First exit out of the application tier by simply typing exit because we actually need to save the contents of our SSH key.

Use the cat command on your SSH key and copy the key.

Log back into the Web tier and create a file to put the key in. As shown the key is now saved in the Web tier. Run the command to change the permissions on the app key and then SSH from to the application tier using the private IP.

chmod 400 your_key_name
ssh -i "jan52023" ec2-user@10.0.3.168

As you can see we were able to connect to the private IP address.

Connect to Private IP address

To connect to the Database from this private instance that we are logged into, we’re going to need to get the endpoint of the database. Go to the RDS dashboard and click on “Databases”. From there click on the hyperlink and copy the endpoint.

Copy Endpoint

In the terminal we first need to install mySQL with the following command.

sudo yum install mysql -y

Now you will enter the command…

mysql -h your_end_point -P 3306 -u admin -p

As you can see I ran into a roadblock. I ran the command multiple times but just could not get it to work. The first thing that should always come to your mind is “Do I have the permissions?”

Failed attempt to log into database

Back to the AWS console I checked the Database security group to make sure that the Application tier even has permissions and it didn’t so I added the type MySQL/Aurora and in custom search for the Application Security group and saved it.

Problem fixed! We’re in. We have connected to our database.

This was a long one I know but if you’ve made it this far thank you so much for sticking with me and if you’d like to follow more of my journey please connect with me on LinkedIn!

Note that these resources do cost money. Make sure to delete the NAT gateway, elastic IP address, terminate all instances and delete the database.

Thank you, Chanel

--

--

Chanel
Nerd For Tech

Cloud/Devops Engineer | AWS | Terraform | Linux 🐧