Setup a 3-Tier Application in AWS: Beginners Guide

Tushar Parasrampuria
9 min readJan 6, 2024

--

The three-tier architecture is the most popular implementation of a multi-tier architecture. It is a comprehensive exercise for someone starting to learn their way of working with AWS. The 3-tier architecture comprises the following:

  • Presentation Tier: It is the communication layer of the application, where the end-user interacts with the application. Web presentation tiers are usually developed using HTML, CSS, and JavaScript.
  • Logic Tier: The Logic tier, also known as the Application tier or Middle tier, is the heart of the application. This is where the information collected is processed based on the application's business logic. The Logic tier is typically developed using Python, Java, Perl, PHP, or Ruby.
  • Data Tier: This is the tier where all the processed application data is stored. This is the most sensitive and critical part of the application. This tier usually has databases such as PostgreSQL, MySQL, OracleDB, MongoDB, and NoSQL.
3-Tier architecture

For this blog, I am going to demo the deployment of a simple 3-tier application. I will be deploying the entire application infrastructure on AWS. So, let’s get started.

What we’ll build

Prerequisite

  • An AWS account
  • Familiarity with basic AWS tools and terminologies
  • Access to a command line tool(Bash/WSL/zsh)

Disclaimer

While I have made every effort to utilize AWS Free Tier eligible resources in the provided configurations and examples, there is a possibility that you may incur charges for certain AWS services. The AWS Free Tier offers limited resources and services free of charge for a specified period.

Building the Base

Just like a house, the base of the application needs to be strong and needs to be built first. Building the base is the most critical part of the infrastructure, once this is set up correctly then building other parts of the application becomes easy.

For our application, we need to set up the following network components:

  • A VPC with a private CIDR of 10.0.0.0/16.
  • Two public subnets with CIDR range of 10.0.1.0/24 and 10.0.2.0/24. One for the Presentation tier and the other for the Logic tier.
  • One private subnet with a CIDR range of 10.0.3.0/24 for the Data Tier.
  • One Internet gateway for public subnets
  • One Elastic IP for NAT gateway
  • One NAT gateway for the private subnet
  • One public route table
  • One private route table

I will be answering in detail about my choice of CIDR in the future blog, So look out for that one. For now, let's continue.

Starting with VPC, navigate to the VPC console in the AWS. Create a VPC with a private CIDR range of 10.0.0.0/16.

Now, create two subnets with a name of project-subnet-public-1 and project-subnet-public-2 and a CIDR range of 10.0.1.0/24 and 10.0.2.0/24 respectively.

Similarly, create another subnet with the name of project-subnet-private-1 and a CIDR range of 10.0.3.0/24.

Once the subnets are created, we need to now make these subnets private and public. Just naming them public/private won’t work, we have to create route tables and define routes that would make public subnet resources accessible from outside. Similarly, we have to create route tables and define routes for private subnets.

Create two route tables, one named as project-rt-private and the other as project-rt-public.

Now, create an Internet gateway named project-igw and a NAT gateway named project-nat. While creating NAT, select the allocate EIP option.

Now, edit the routes of the private route table and add the following route to the NAT gateway. This makes the route table private.

Similarly, edit the routes of the public route table and add the following route to the Internet gateway. This makes the route table public.

Further, edit both the public route tables and enable the automatic public IP allocation setting.

Note: This step is only for public route table not for private route table

Now, the final steps in making the subnets private/public. Edit the route table association for the private subnet and attach it to the private route table. Similarly, change the route table for public subnets to the public route table.

Finally, we have created the private and public subnets and the base of our application should now look like this:

With this, we have completed the setup of the base.

Create Launch Templates

I have seen many blogs where it starts with building the Presentation Tier first, but I have never subscribed to that thought process. Whenever I have tried building the Presentation layer first, I have often ended up juggling between the layers multiple times and finally ending up spending more time than needed for the setup.

However, our Database is in a private subnet, so we will need to launch the front-end EC2 instance so that we can ssh into the Database tier and start the provisioning. In an Ideal scenario, we will create a Bastion to access resources in a private subnet.

For now, let's start by start by creating a Launch template with the name project-lt for the Presentation tier by selecting the following config.

Similarly, Create a launch template with the name project-lt-backend for the Data tier by selecting the project-subnet-public-2 subnet and creating the following security-group rules.

Similarly, Create a launch template with the name project-lt-db for the Data tier by selecting the project-subnet-private-1 subnet and creating the following security-group rules.

Now, launch an EC2 instance using each of the created three launch templates one by one.

Data Tier

Every application stores important data about the application such as session info, username, password, user details, etc in the Database. For our example, we are going to use MySQL DB.

First test the SSH to the Frontend instance. The public IP for my frontend instance is 54.237.25.130. So the command to ssh will be

ssh -i project-keypair.pem ec2-user@54.237.25.130

Please change the IP accordingly for your case.

Now, exit out of the frontend instance and copy the SSH private key of the Database instance into the frontend instance. As I have used the same SSH key, so I will be copying the project-keypair.pem file.

scp -i project-keypair.pem project-keypair.pem ec2-user@54.237.25.130:/home/ec2-user

Once the key is copied, SSH into the frontend instance and change the permissions of the key file to 400.

sudo chmod 400 /home/ec2-user/project-keypair.pem

Now, SSH into the Database instance using its private IP. The private IP of my Database Instance is 10.0.3.27

ssh -i /home/ec2-user/project-keypair.pem ec2-user@10.0.3.27

Now install the MySQL server.

sudo amazon-linux-extras install epel -y
sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm
sudo yum install mysql-community-server

Start the MySQL server.

sudo systemctl start mysqld 

During the installation, an initial password is configured for the MySQL root account. You can find this password in the MySQL log file.

cat /var/log/mysqld.log | grep "A temporary password"

The MySQL server is ready to use now. From the terminal, run the below command to connect to the MySQL command line interface.

mysql -u root -p 

It will prompt for the root account password. Use the temporary password you got earlier. On successful authentication, you will get the MySQL prompt.

Before you can proceed, we need to alter the temporary root user password. Run, this command with your choice of password.

ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@1234';

Now we need to create the Database named example.

CREATE DATABASE example;

To be able to store data, our backend server needs to communicate with the Database. So, create an admin user with a password as Admin@1234 for our backend service. Use the private IP of the backend instance launched earlier. In my case, the IP is 10.0.2.72.

CREATE USER 'admin'@'10.0.2.72' IDENTIFIED BY 'Admin@1234';
GRANT ALL PRIVILEGES ON example.* TO 'admin'@'10.0.2.72';
FLUSH PRIVILEGES;

Finally, we are done with setting up the Database.

Logic Tier

The Logic/Application Tier is the heart of our application. This is the place that connects the Presentation and Data Tier. It holds the Business logic of the application.

For our example, we are using Flask as the backend app. Let's start by logging into the backend EC2.

Similar to the SSH process for Database, we will need to first SSH into the frontend instance, and then we can SSH into the backend instance. The private IP for my backend EC2 is 10.0.2.72

ssh -i /home/ec2-user/project-keypair.pem ec2-user@10.0.2.72

Now, install the Flask dependencies.

sudo yum install python3-pip
pip3 install Flask mysql-connector-python
pip3 install flask-cors

Now, copy the flask code from here into the file named backend.py and replace the following part of the code accordingly.

# Set up MySQL connection
db = mysql.connector.connect(
host="10.0.3.27",
user="admin",
password="Admin@1234",
database="example"
)

Run the Flask app.

python3 backend.py

We are done with setting up the Backend server as well.

Presentation Tier

Almost there, Now it's time to build the last tier of our application. The Presentation tier is the environment where we will launch our EC2 server that will host the front end of our application. We are using an Apache server hosting a simple HTML and Javascript-based frontend.

Start by installing the dependencies.

sudo yum install httpd

Start the server

sudo systemctl start httpd

Update the /var/www/html/index.html page with the following file and replace the following part of the code with your Backend server’s public IP accordingly.

fetch('http://54.198.65.210:5000/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ textValue: textValue }),
mode: 'cors'
})

Restart the server

sudo systemctl restart httpd

Now visit the frontend URL(http://frontend-public-ip:80) from a web browser.

Putting It all together

Now, let's test this. Go to the Web page. Enter a text and hit the submit button.

If everything went well, you should see a dialog box as follows:

Let's check our DB if the data indeed was saved there or not.

Success!

Phew! That was quite a journey. We have successfully set up a 3-tier application entirely on AWS. I know this was quite excruciating, but we took it step-by-step breaking it down into smaller parts. I hope you were able to set up the application successfully.

Remember to delete your resources (EC2, EIP, NAT Gateway) so you don’t incur any charge!

Thank you

Thank you for following through with me on this article. I hope you enjoyed it as much as I did writing it. I would love for your continued support. Please follow me for more such content.

--

--