Establish a Classic 3-Tier Architecture in AWS | by Steven Laszloffy | May, 2022

Let’s create!

This week’s project tasks us with establishing a traditional 3-tier architecture in Amazon Web Services. The three tiers are generally referred to as the Web or Presentation tier, the Application tier, and the Database (or just plain Data) tier. Let’s run through each component real quick:

  • Web Tier — This will generally be the public-facing side of your project. Whether it’s a website or GUI, this is what the user sees and interacts with. For our project, we’ll have an auto-scaling group of EC2 instances running Apache to host a simple HTML site, contained inside a couple of subnets in a VPC that connect to the internet via a gateway. A Security Group will restrict traffic to these instances to HTTP only.
  • Application Tier — This tier, as it may sound, is usually where the actual logic, or code, or “brain” of your project will sit. Traffic will be passed from the Web tier to this tier for processing. In our example, we will have an auto-scaling group of EC2 instances inside of private subnets. A security group will make sure that only traffic directly from the Web tier can come through. For this project, we’re not actually going to have any running code.
  • Database Tier — The final tier is basically storage. It will contain any databases for your solution needs, or storage devices, such as an S3 bucket. In our project, this will be a MySQL RDS Database, housed in a couple private subnets. As before, a Security Group will restrict traffic to only inbound from the Application tier.

I’ve attempted to diagram this out, so this is what it might look like logically:

For this project, all we are going to need is an AWS account with admin access. (As always, do not use your root account)

Let’s do this!

Create a VPC
To start, we’re going to be in our AWS Console, and navigate to the VPC dashboard.

We’re nerds. We love wizards.

As with everything else in the console, let’s look at the top right for our ‘Create VPC’ button.

This next screenshot shows a nifty feature that allows you to create a large portion of the assets for this project in one go. I seem to be a glutton for punishment, however, and will be breaking things up a bit to keep to my “three distinct tiers” approach.

So instead, we select ‘VPC only’, name it, give it a CIDR block, and boom. Step one is complete.

Create Some Subnets
Next, we’re going to work our way down the menu on the left side, and select ‘Subnets’. Look for the ‘Create Subnet’ button, and push it.

Click ‘Add new subnet’ to create more than one at a time, then click ‘Create subnet’ when you’re finished.

Booyah. Success.

Routing Tables
This is a page that we’ll be coming back to a few times, but right now we’re going to create a routing table for the two subnets we’ve just established. This will allow the instances to talk to each other, and later on, with the Internet Gateway. Like with the subnets, it’s the next option down on the left hand side of your console, and zwoop! to the top right for ‘Create route table ‘

Be sure to manually select the right VPC, as we are not using the default.

Once we have the table, we need to associate the subnets with the table:

Select the associations tab, then ‘Edit subnet associations’
Select both subnets and ‘Save’

This creates an “explicit” association. Suffice it to say, there can be implicit, but we’re not going to be dealing with those today. I should also point out here, that by default, any route table that is created, will have a default route entry called ‘local’. This route allows any instances to communicate with any other instances that are within subnets that are using this table.

Another step that will need to be done, is make this table the “main” table for the VPC.

The Gateway to the Interwebs
Simply called an Internet Gateway, this next asset allows the subnets we’ve previously created to access the internet at large, thus becoming “Public subnets”

Once again, let’s drop down to the next option!

This next step is to “attach” the gateway to the VPC that we created at the beginning.

Directly after creation, the notification header provides an easy link to our next step, but the Actions > Attach to VPC option will always be there for us.

Follow the prompts, select the correct VPC, and we’re on to the next piece!
At this point, we can also add the gateway to our routing table:

Create a Security Group
Security groups are vital as a “instance-level” firewall of sorts. Here, we’re going to create one that will only allow HTTP traffic in.

Create an Auto Scaling Group
By navigating to EC2 > Auto Scaling groups, we can find the typical ‘Create XYZ’ wizard, but upon starting the wizard, I realized that I really needed to create a Launch Template first. I have covered creating and using a launch template previously, but there’s enough unique characteristics for this project that I’ll walk us through it again here.

Not shown is the bootstrap script I’ve used on previous projects being placed in the User Data field at the very bottom of this wizard page.

Now that we’ve created the launch template, we can go back to the Auto Scaling Group (ASG) wizard, and continue:

Everything else is left as default, and we could actually utilize the ‘Skip to review’ button on the above page, but regardless.. complete the wizard, and once our instances finish initializing, we can grab one of their public IPs and see our favorite little html page:

Note: for some weird reason, my normal bootstrap script was failing, so I had to add a install php command in order for the Apache webserver to start.

And thus concludes our first tier. *throws confetti* Grab some liquid energy, your hats, and possibly the cat, and let’s move on!

Create More subnets
Navigating back to our VPC > Subnet page, we’re going to create two more subnets:

This time, we’re not going to attach them to the internet gateway, thus making them “Private” subnets. We will, however, need to associate them with a route table.

Create our App Security Group
The fun thing about this one, is it will only allow traffic from our Web Security Group!

That VPC dropdown is a tricky bit… use the Web security group’s ID to create the Inbound rule.

Auto Scale Strikes Again!
We will be creating another launch template/Auto Scale group combo, but this one will only be launching EC2 instances with just an OS on them. You’ve seen the options before, so I just named my launch template USAFBlueprintand my ASG BaseDorms. Complete the wizard, and those will start spinning up!

Create a NAT Gateway
Now really, this bit could actually go any point after the creation of the first public subnet, but we’ll put it here. Important bit is definitely selecting the right subnet, ensuring it’s a Public type, and allocating an elastic IP.

This will allow our private subnets to talk with the public side of the house.

Now, at this point, we can either navigate back to the route tables, and add the NAT gateway ID as a route entry in the App tier Private route table (BaseMap), or we can wait until later, and add it to both Private route tables (BaseMap/FortMap). Either way, it will look something like this:

And there we have our Application tier! On to our last stop…

Yet another Security Group…
This one only allows MySQL traffic from my Application tier security group: SecurityForces.

Create the Database
Next, we’re going to create a MySQL RDS database. Now these screenshots may make it seem like I was able to just flow right through this, but I actually ended up having to back up a few steps to prep this stage..

  • database wouldn’t create because it needed subnets that were spread over at least two Availability Zones
  • because I had created all my subnets with basically “let Amazon choose the AZ”, they were all in the same AZ.
  • I ended up having to delete/recreate my last subnet, and place it manually in a different AZ.
  • I then created the DB subnet group, and was able to complete the database creation.

Now we’re back on track!

For this project we didn’t use Multi-AZ DB options, but any option other than strictly “Free Tier” will unlock the options in the center box, thus enabling Multi-AZ.

There’s a big section of options in-between these two screenshots, but these were the only pertinent options.

And there you have it! The Database Tier!

A big note here though is that this project:

  1. did not have any functionality for the Application Tier
  2. did not actually have any connections to the Database Tier but was intended more to show the process one might use to create something similar.

Before we finish, however.

Testing Web to App

Simply put, a Bastion host (or in older parlance, a jump server) is an additional way to lock down your architecture, but still, allow an access point for certain actions. In this case, we’re going to create a bastion host to test and see that our web tier can talk to our app tier!

Our Bastion Host (aka SpaceWarningSqdn) will be placed inside our public subnet, and be granted rights (again, through our Security groups) to ping a private IP of one of our Application Tier instances.

Unfortunately, through a muddle of it being 4 am, and a LONG chain of testing different rule configurations to actually get it working, I lost most of my screenshots. But here’s the one of the ping actually working!

Three-tier architecture is a great way to build out an entire stack of services, as it allows you to break it up logically, get each piece working individually, and then connect the dots for a fully functional, epic project.

Thank you for sticking with me, I’ll see ya next time!

Leave a Comment