Build a 3-Tier VPC Architecture

Design a production-style 3-tier VPC with ALB, EC2, and RDS on AWS.

Introduction

30 Second Summary

Every time you use an app, your request travels through layers of network infrastructure designed to keep data safe and systems organized. Banks, hospitals, and tech companies all rely on a specific architecture pattern to separate public-facing traffic from sensitive internal systems.

In this project, you will build a 3-tier VPC architecture on AWS. This is the exact network design that cloud engineers deploy in production and get asked about in interviews.

What You'll Build

A fully functional three-tier network on AWS with traffic flowing from the internet through an Application Load Balancer, to an EC2 application server, to an RDS MySQL database.

By the end of this project, you'll have:

  • A custom VPC with 6 subnets spanning 2 Availability Zones, separating web, app, and data traffic.
  • Three security groups that enforce strict tier-to-tier isolation using security group references.
  • A working application stack with an Application Load Balancer routing internet traffic to an EC2 instance that connects to an RDS MySQL database in isolated private subnets.
  • Secret Mission: Add a second EC2 instance in another Availability Zone and verify the ALB distributes traffic across both, proving high availability.

Are there any prerequisites?

You need an AWS account with console access. No local software installation is required. All work in this project happens directly in the AWS Management Console.

Create Your VPC and Network Foundation

Every cloud application lives inside a network. On AWS, that network is a VPC (Virtual Private Cloud). It gives you full control over IP addresses, subnets, routing, and who can talk to whom.

In this step, you will build the network skeleton for a 3-tier architecture. You will carve out six subnets across two Availability Zones, then connect the public layer to the internet.

In this step, get ready to:
  • Create a custom VPC with a /16 CIDR block.
  • Create 6 subnets across 2 Availability Zones (public, app, and data tiers).
  • Attach an Internet Gateway and configure a public route table.
Create the VPC

A CIDR block defines the IP address range available inside your VPC. The block 10.0.0.0/16 gives you 65,536 addresses to divide among your subnets.

  • In the AWS Management Console, type VPC in the top search bar and select VPC from the results.
  • On the VPC dashboard, click Create VPC.
  • Under Resources to create, select VPC only.
  • In the Name tag field, enter ThreeTierVPC.
  • For IPv4 CIDR block, choose IPv4 CIDR manual input and enter 10.0.0.0/16.
  • Leave the IPv6 CIDR block option as-is (no IPv6).
  • Leave Tenancy set to Default.
  • Click Create VPC.

You should see a green success banner confirming ThreeTierVPC was created.

Now you need to enable DNS hostnames so EC2 instances launched in this VPC receive public DNS names.

  • In the left navigation pane, click Your VPCs.
  • Select the checkbox next to ThreeTierVPC.
  • Click the Actions dropdown, then select Edit VPC settings.
  • Under DNS settings, check the box for Enable DNS hostnames.
  • Click Save.

Why enable DNS hostnames?

DNS hostnames let your EC2 instances receive public DNS names that map to their public IPs. Without this setting, services like the Application Load Balancer cannot resolve instance addresses inside the VPC.

Don't see your new VPC?

Make sure you are in the correct AWS Region. The region selector is in the top-right corner of the console. Your VPC only exists in the region where you created it.

help me find my VPC in the console

Create 6 subnets across 2 Availability Zones

Subnets divide your VPC's IP range into smaller segments. Each subnet lives in exactly one Availability Zone. By spreading subnets across two AZs, you protect against a single data center failure.

You will create six subnets using a naming convention where the tens digit of the third octet identifies the tier: 0x for web, 1x for app, and 2x for data.

  • In the left navigation pane, click Subnets.
  • Click Create subnet.
  • In the VPC ID dropdown, select ThreeTierVPC.

Now configure the first subnet with these settings:

  • Set Subnet name to Public-Web-1a.
  • Select the first Availability Zone ending in a (for example, us-east-1a).
  • Set IPv4 subnet CIDR block to 10.0.1.0/24.

Click Add new subnet at the bottom to add the remaining five subnets in a single batch. Configure each one as follows:

  • Subnet 2: Name Public-Web-1b, AZ ending in b, CIDR 10.0.2.0/24.
  • Subnet 3: Name Private-App-1a, AZ ending in a, CIDR 10.0.10.0/24.
  • Subnet 4: Name Private-App-1b, AZ ending in b, CIDR 10.0.11.0/24.
  • Subnet 5: Name Private-Data-1a, AZ ending in a, CIDR 10.0.20.0/24.
  • Subnet 6: Name Private-Data-1b, AZ ending in b, CIDR 10.0.21.0/24.
  • Click Create subnet.

You should see all 6 subnets listed in the Subnets page.

Next, enable auto-assign public IPv4 on the two public subnets so any instance launched there automatically gets a public IP.

  • Select the checkbox next to Public-Web-1a.
  • Click Actions, then Edit subnet settings.
  • Check the box for Enable auto-assign public IPv4 address.
  • Click Save.
  • Repeat this process for Public-Web-1b.

Why two AZs?

Each Availability Zone is a physically separate data center within an AWS Region. If one AZ suffers an outage, resources in the other AZ keep running. Spreading each tier across two AZs is the foundation of high availability on AWS.

Seeing a CIDR overlap error?

Each subnet's CIDR must be a unique range within the VPC's 10.0.0.0/16 block. Double-check you did not repeat a CIDR (like using 10.0.1.0/24 twice). Also confirm you selected ThreeTierVPC as the VPC at the top of the form.

help me fix a CIDR overlap error when creating subnets

Create and attach an Internet Gateway

An Internet Gateway is the door between your VPC and the public internet. Without it, nothing inside your VPC can reach the outside world (and vice versa).

After creating the gateway, you will build a route table that tells the public subnets how to reach the internet through it.

  • In the left navigation pane, click Internet gateways.
  • Click Create internet gateway.
  • Set the Name tag to ThreeTier-IGW.
  • Click Create internet gateway.

Now attach the gateway to your VPC.

  • On the Internet gateway details page, click Actions, then Attach to VPC.
  • Select ThreeTierVPC from the dropdown.
  • Click Attach internet gateway.

The state should change to Attached. Next, create a public route table.

  • In the left navigation pane, click Route tables.
  • Click Create route table.
  • Set the Name to Public-RT.
  • Select ThreeTierVPC as the VPC.
  • Click Create route table.

Add a route that sends all internet-bound traffic to the gateway.

  • With Public-RT selected, click the Routes tab at the bottom.
  • Click Edit routes.
  • Click Add route.
  • In the Destination field, enter 0.0.0.0/0.
  • In the Target field, select Internet Gateway, then choose ThreeTier-IGW.
  • Click Save changes.

Finally, associate this route table with both public subnets.

  • Click the Subnet associations tab.
  • Click Edit subnet associations.
  • Check the boxes next to Public-Web-1a and Public-Web-1b.
  • Click Save associations.

What does 0.0.0.0/0 mean?

The destination 0.0.0.0/0 is a catch-all that matches any IP address not covered by a more specific route. Pointing it at the Internet Gateway means "send all non-local traffic to the internet." Only subnets associated with this route table become truly public.

Internet Gateway shows Detached?

Go back to Internet gateways in the left navigation. Select ThreeTier-IGW, then Actions and Attach to VPC. Make sure you select ThreeTierVPC from the dropdown. A VPC can only have one Internet Gateway attached at a time.

help me attach my Internet Gateway to my VPC

Your network foundation is in place. You have a VPC, six subnets organized by tier and AZ, and a public route to the internet. Next up, you will create security groups that control exactly which traffic can flow between each tier.

Configure Security Groups

Your VPC now has 6 subnets and an Internet Gateway. But without traffic rules, everything is wide open. Security Groups act as virtual firewalls that control which traffic can reach each tier of your architecture.

In this step, you will create three security groups that enforce strict tier-to-tier communication. Each security group references the one above it, forming a chain that only allows traffic to flow in the correct direction.

In this step, get ready to:
  • Create a Web Tier security group for the Application Load Balancer.
  • Create an App Tier security group for the EC2 instance.
  • Create a Data Tier security group for the RDS database.
Create the web tier security group

The web tier security group protects the Application Load Balancer. It needs to accept HTTP and HTTPS traffic from the public internet so that users can reach your application.

  • In the VPC Console, click Security Groups in the left navigation pane.
  • Click Create security group.
  • In the Security group name field, enter Web-Tier-SG.
  • In the Description field, enter Allow HTTP and HTTPS from the internet.
  • For VPC, remove the default VPC and select ThreeTierVPC.
  • Scroll down to the Inbound rules section and click Add rule.
  • Set Type to HTTP. The port auto-fills to 80.
  • Set Source to Anywhere-IPv4 (0.0.0.0/0).
  • Click Add rule again to add a second inbound rule.
  • Set Type to HTTPS. The port auto-fills to 443.
  • Set Source to Anywhere-IPv4 (0.0.0.0/0).
  • Leave the Outbound rules section as the default (all traffic allowed).
  • Click Create security group.

What is 0.0.0.0/0?

The CIDR 0.0.0.0/0 means "all IPv4 addresses." Setting it as the source allows any device on the internet to send traffic to this security group on the specified port.

This is appropriate for the web tier because your ALB is the public entry point. Users from anywhere need to reach it.

You should see a green success banner confirming the security group was created.

Create the app tier security group

The app tier security group protects your EC2 instance. Instead of allowing traffic from the entire internet, this security group only accepts traffic from the web tier security group. This is called security group chaining.

  • Click Create security group again.
  • In the Security group name field, enter App-Tier-SG.
  • In the Description field, enter Allow HTTP from Web-Tier-SG only.
  • For VPC, remove the default VPC and select ThreeTierVPC.
  • In the Inbound rules section, click Add rule.
  • Set Type to HTTP. The port auto-fills to 80.
  • For Source, click the search field and type Web-Tier-SG. Select the Web-Tier-SG security group from the dropdown.
  • Leave the Outbound rules section as the default (all traffic allowed).
  • Click Create security group.

What is security group chaining?

Instead of using a CIDR range (like 0.0.0.0/0) as the source, you reference another security group. This means only resources attached to that specific security group can send traffic.

In your architecture, the App-Tier-SG only allows traffic from Web-Tier-SG. Even if someone discovers the EC2 instance's public IP, they cannot access it directly because the request does not originate from a resource in Web-Tier-SG.

This pattern maps to interview questions

Cloud engineering interviews frequently ask "how do you isolate tiers in a VPC?" The answer is security group references. This is the exact pattern you are building right now.

Create the data tier security group

The data tier security group protects your RDS database. It only accepts MySQL traffic from the app tier, completely isolating the database from the internet and from the web tier.

  • Click Create security group again.
  • In the Security group name field, enter Data-Tier-SG.
  • In the Description field, enter Allow MySQL from App-Tier-SG only.
  • For VPC, remove the default VPC and select ThreeTierVPC.
  • In the Inbound rules section, click Add rule.
  • Set Type to MySQL/Aurora. The port auto-fills to 3306.
  • For Source, click the search field and type App-Tier-SG. Select the App-Tier-SG security group from the dropdown.
  • Leave the Outbound rules section as the default (all traffic allowed).
  • Click Create security group.

Why does the data tier only accept from App-Tier-SG?

Your database should never be reachable from the internet or even directly from the load balancer. Only the application server needs database access. By referencing App-Tier-SG as the sole source, you ensure that the only path to your data is through the application layer.

You now have three security groups forming a chain: internet traffic enters through Web-Tier-SG, flows to App-Tier-SG, and finally reaches Data-Tier-SG. No tier can be bypassed.

Don't see ThreeTierVPC in the VPC dropdown?

Make sure you are in the same AWS Region where you created the VPC in the previous step. Check the Region selector in the top-right corner of the console.

help me find my VPC when creating a security group

Your security groups are locked down. Next up, you will deploy an EC2 instance into the app tier and prove that the security group isolation actually works.

Deploy the Application Tier

Your network foundation is locked down with security groups that control exactly which tier can talk to which. Now it is time to put something inside those tiers.

In this step, you will launch an EC2 instance that runs a simple web server. The interesting part is where you place it and how the security group protects it.

In this step, get ready to:
  • Launch an EC2 instance with a startup script that installs Apache.
  • Verify the instance is running and confirm that its security group blocks direct public access.
Launch an EC2 instance

You will launch an instance in the public subnet so it can reach the internet without a costly NAT Gateway. The App-Tier-SG security group ensures the instance still cannot be accessed directly from the public internet on port 80.

  • In the AWS Console search bar, type EC2 and select the EC2 service.
  • Click Launch instance from the EC2 Dashboard.
  • Under Name and tags, enter App-Tier-EC2-AZ-a as the instance name.
  • Under Application and OS Images (Amazon Machine Image), choose Amazon Linux 2023 from the Quick Start list. Make sure the selected AMI is marked Free tier eligible.
  • Under Instance type, select t2.micro (or t3.micro if t2.micro is not available in your region). Both are Free tier eligible.
  • Under Key pair (login), select Proceed without a key pair (Not recommended). You will use EC2 Instance Connect later instead of SSH keys.
  • Under Network settings, click Edit.
  • For VPC, select ThreeTierVPC.
  • For Subnet, select Public-Web-1a.
  • For Auto-assign public IP, confirm it is set to Enable.
  • Under Firewall (security groups), choose Select existing security group.
  • Select App-Tier-SG from the dropdown. Remove any other security groups if they are preselected.

Now scroll down to the Advanced details section to add the startup script.

  • Expand the Advanced details section at the bottom of the page.
  • Scroll down to the User data field.
  • Paste the following script into the User data field:
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Hello from the App Tier - AZ-a</h1><p>Instance ID: $(curl -s http://169.254.169.254/latest/meta-data/instance-id)</p>" > /var/www/html/index.html

What does this user data script do?

This script runs automatically when the instance first boots. It updates system packages, installs Apache HTTP Server, starts the web server, and creates a simple HTML page.

The HTML page displays which Availability Zone the instance is in and its unique instance ID. This becomes important later when you test load balancing across multiple instances.

  • Leave all other settings at their defaults.
  • In the Summary panel on the right, review your configuration.
  • Click Launch instance.

Why place the EC2 instance in a public subnet?

In a production environment, the app tier would sit in a private subnet with a NAT Gateway providing outbound internet access. A NAT Gateway costs approximately $0.045/hour (around $32/month), which is expensive for a learning project.

By placing the instance in a public subnet but assigning it the App-Tier-SG security group (which only allows inbound traffic from Web-Tier-SG), you get the same isolation effect. The instance has internet access for updates, but no one can reach it directly on port 80.

Launch failed or instance terminated immediately?

Make sure you selected ThreeTierVPC (not the default VPC) and the Public-Web-1a subnet. If the instance terminates, check that the AMI you chose is Free tier eligible for your region.

Help me troubleshoot my EC2 instance launch failure in the ThreeTierVPC.

Verify EC2 is running and test security group isolation
  • Click the instance ID link in the success notification to go to the Instances page.
  • Wait for the Instance state column to show Running. This takes about a minute.
  • Select the instance checkbox and click the Status checks tab in the lower details panel.
  • Wait until both status checks show passed. This can take 2-3 minutes.

Now test that the security group isolation is working.

  • Select the instance and find its Public IPv4 address in the Details tab.
  • Copy the public IP address.
  • Open a new browser tab and paste the IP address into the URL bar. Press Enter.
  • Wait about 10-15 seconds. The page should time out and fail to load.

Why does the browser time out?

Your browser is trying to reach the instance on port 80 directly from the internet. The App-Tier-SG only allows inbound HTTP traffic from the Web-Tier-SG security group. Since your browser is not coming through the Web-Tier-SG, the request is blocked.

This is your security group isolation in action. Even though the instance has a public IP and Apache is running, no one can reach it unless they come through the load balancer you will set up in a later step.

Page loaded instead of timing out?

If you can see the web page, the wrong security group is attached. Go back to your instance, select Actions > Security > Change security groups. Remove any security group other than App-Tier-SG.

Help me fix my EC2 security group so it only allows traffic from Web-Tier-SG.

Your app tier is live and locked down. No one can reach it directly, which is exactly the point. Next, you will deploy the data tier so your application has a database to connect to.

Deploy the Data Tier

In the previous step, you launched an EC2 instance and proved that your security group isolation works. Direct access to the instance is blocked because App-Tier-SG only allows traffic from Web-Tier-SG.

Now it is time to build the data tier. You will deploy an RDS MySQL database into the private data subnets you created in Step 1. The database will be completely hidden from the internet, and only your EC2 app server will be able to reach it.

In this step, get ready to:
  • Create a DB subnet group that tells RDS which private subnets to use.
  • Launch an RDS MySQL instance in the isolated data tier.
  • Verify database connectivity from your EC2 instance.
Create a DB subnet group

RDS needs to know which subnets it can place your database in. A DB subnet group is a collection of subnets you designate for your database instances. It must span at least two Availability Zones for redundancy.

  • Navigate to the RDS Console by typing RDS in the AWS search bar at the top and selecting **Amazon RDS**.
  • In the left navigation pane, click Subnet groups.
  • Click Create DB Subnet Group.
  • For Name, enter threetier-db-subnet-group.
  • For Description, enter DB subnet group for three tier VPC.
  • For VPC, select ThreeTierVPC from the dropdown.
  • In the Add subnets section, select both Availability Zones (the ones ending in a and b) from the Availability Zones dropdown.
  • Under Subnets, select the two private data subnets: 10.0.20.0/24 (Private-Data-1a) and 10.0.21.0/24 (Private-Data-1b).
  • Click Create.

What is a DB subnet group?

A DB subnet group tells RDS which subnets (and therefore which Availability Zones) are available for placing your database. By including subnets in two AZs, you give RDS the option to failover to a second zone if you ever enable Multi-AZ in the future.

Because you are using Private-Data-1a and Private-Data-1b, the database will always live in a subnet with no internet route. This is network isolation at the infrastructure level.

  • Confirm the new subnet group appears in the Subnet groups list showing threetier-db-subnet-group with status Complete.

Don't see your subnet group?

Make sure you selected ThreeTierVPC as the VPC. If you accidentally used the default VPC, the private data subnets will not appear in the subnet list.

Also check that you selected subnets in at least two different Availability Zones. RDS requires a minimum of two AZs per subnet group.

help me troubleshoot my DB subnet group creation

Launch an RDS MySQL instance

With the subnet group ready, you can launch the database. You will use the Free tier template to keep costs at zero.

  • In the RDS Console navigation pane, click Databases.
  • Click Create database.
  • Select Standard create.
  • For Engine type, select MySQL.
  • Under Templates, select Free tier.
  • For DB instance identifier, enter threetier-db.
  • For Master username, enter admin.
  • For Master password, choose a strong password and note it down somewhere safe. You will need it later to connect.
  • For DB instance class, confirm it is set to db.t3.micro (Free tier eligible).
  • For Storage type, select General Purpose SSD (gp2).
  • For Allocated storage, enter 20 GB.
  • Under Connectivity, for Virtual private cloud (VPC), select ThreeTierVPC.
  • For DB subnet group, select threetier-db-subnet-group.
  • For Public access, select No.
  • For VPC security group (firewall), select Choose existing.
  • Under Existing VPC security groups, select Data-Tier-SG. Remove the default security group if it was automatically added.
  • Leave Availability Zone set to No preference.
  • Scroll to the bottom and click Create database.

Why set Public access to No?

Setting Public access to No means AWS will not assign a public IP to the database endpoint. Combined with the Data-Tier-SG (which only allows port 3306 from App-Tier-SG), the database is doubly isolated. No one on the internet can reach it directly.

RDS creation takes 5-15 minutes

Your database status will show Creating for several minutes. Wait for it to change to Available before moving to the next substep. You can refresh the page to check the status.

  • Wait for the status of threetier-db to change to Available in the Databases list.
  • Click on threetier-db to open its details. Under the Connectivity & security tab, locate the Endpoint value. Copy this endpoint and save it. You will need it in the next substep.

Database stuck in Creating?

RDS database creation typically takes 5-15 minutes. If it has been more than 20 minutes, refresh the page. Some regions experience longer provisioning times during peak usage.

If you see a creation failure, double-check that you selected threetier-db-subnet-group (not a default subnet group) and that Data-Tier-SG was assigned.

help me troubleshoot my RDS instance creation

Verify database connectivity from EC2

The ultimate test of your data tier isolation is connecting to the database from inside the VPC. You will SSH into your EC2 instance using EC2 Instance Connect (a browser-based terminal) and then connect to the RDS endpoint using the MySQL client.

  • Navigate to the EC2 Console by typing EC2 in the AWS search bar and selecting EC2.
  • In the left navigation pane, click Instances.
  • Select your EC2 instance (the one running in Public-Web-1a).
  • Click Connect at the top of the page.
  • Choose the EC2 Instance Connect tab.
  • Click Connect. A browser-based terminal window will open.

What is EC2 Instance Connect?

EC2 Instance Connect lets you open a terminal session to your instance directly from the AWS Console. It pushes a temporary SSH key to your instance for 60 seconds, so you do not need to manage SSH key pairs. It works with Amazon Linux 2023 instances that have a public IP address.

  • Install the MySQL client by running this command in the terminal:
sudo yum install -y mariadb105

Why mariadb105?

On Amazon Linux 2023, the MySQL command-line client is provided by the mariadb105 package. MariaDB's client is fully compatible with MySQL and provides the mysql command you need to connect to your RDS instance.

  • Once the installation finishes, connect to your RDS database by running the following command. Replace the endpoint placeholder with the RDS endpoint you copied earlier:
mysql -h [[RDS_ENDPOINT="your RDS endpoint from the Connectivity & security tab"]] -u admin -p
  • When prompted, enter the master password you chose during RDS creation.
  • You should see a MySQL prompt. Run this test query:
SHOW DATABASES;
  • You should see a list of default MySQL databases (like information_schema, mysql, performance_schema, and sys).
  • Type exit to close the MySQL connection.

What does this prove?

Your EC2 instance (protected by App-Tier-SG) successfully connected to the RDS database (protected by Data-Tier-SG) on port 3306. This works because Data-Tier-SG explicitly allows inbound traffic from App-Tier-SG.

Meanwhile, no one on the internet can reach this database. It has no public IP, lives in private subnets with no internet route, and its security group only accepts connections from your app tier.

Connection timed out?

If the mysql command hangs or times out, check that Data-Tier-SG has an inbound rule for port 3306 with the source set to App-Tier-SG (the security group ID, not a CIDR block).

Also confirm that your EC2 instance is associated with App-Tier-SG. The outbound rule on App-Tier-SG must allow all traffic (which is the default).

Finally, verify that the RDS instance status is Available (not Creating or Backing-up).

help me debug my EC2-to-RDS connection

Your data tier is live and locked down. The database sits in private subnets with no public access, and only your app tier can reach it. Next up, you will deploy the web tier with an Application Load Balancer that ties all three tiers together into a working application.

Deploy the Web Tier and Test End-to-End

You have an EC2 instance serving a web page and an RDS database tucked away in private subnets. The problem is that nobody on the internet can reach your application. The App-Tier-SG blocks all direct traffic.

The missing piece is an Application Load Balancer sitting in the public subnets. The ALB accepts internet traffic through Web-Tier-SG, then forwards it to your EC2 instance through the security group reference chain. This is the final link that completes the 3-tier flow.

In this step, get ready to:
  • Create an internet-facing Application Load Balancer in your public subnets.
  • Create a target group and register your EC2 instance.
  • Test the full traffic flow from the internet through all three tiers.
Create an Application Load Balancer

An Application Load Balancer is a fully managed AWS service that distributes incoming HTTP traffic across multiple targets. It lives in your public subnets and serves as the single entry point for internet users.

  • In the AWS Console, navigate to the EC2 service.
  • In the left sidebar, scroll down to the Load Balancing section and click Load Balancers.
  • Click Create load balancer.
  • Under Application Load Balancer, click Create.

You are now on the ALB configuration page. Fill in the settings below.

  • For Load balancer name, enter ThreeTier-ALB.
  • For Scheme, select Internet-facing.
  • Under Network mapping, select ThreeTierVPC from the VPC dropdown.
  • Select both Availability Zones and choose Public-Web-1a for the first AZ and Public-Web-1b for the second AZ.
  • Under Security groups, remove the default security group.
  • Select Web-Tier-SG from the list.

Why Web-Tier-SG on the ALB?

The ALB is the public-facing component of your architecture. Web-Tier-SG allows HTTP (port 80) and HTTPS (port 443) from the entire internet. This is intentional because the ALB is the only resource that should accept direct public traffic.

Your EC2 instance uses App-Tier-SG, which only allows traffic from Web-Tier-SG. Because the ALB carries Web-Tier-SG, traffic from the ALB is permitted through to EC2. This is the security group chaining pattern in action.

Leave the Listeners and routing section for now. You will create the target group next and come back to configure it.

Create a target group and register your EC2 instance

A target group tells the ALB where to send traffic. You will create one that points to your EC2 instance on port 80.

  • In the Listeners and routing section of the ALB creation page, find the Default action row for the HTTP:80 listener.
  • Click Create target group. This opens a new tab.

In the new tab, configure the target group settings.

  • For Choose a target type, select Instances.
  • For Target group name, enter AppTier-TG.
  • For Protocol, keep HTTP on port 80.
  • For VPC, select ThreeTierVPC.
  • Under Health checks, keep the health check path as /.
  • Click Next.

What is a health check?

The ALB periodically sends an HTTP request to each registered target at the health check path. If the target responds with a 200 status code, the ALB considers it healthy and sends traffic to it. If the target fails consecutive health checks, the ALB stops routing traffic to it.

Using / as the path means the ALB checks the root page. Your Apache server returns the "Hello from the App Tier" page, which gives a 200 response.

You are now on the Register targets page.

  • In the list of available instances, select the checkbox next to your EC2 instance (the one running in Public-Web-1a).
  • Click Include as pending below.
  • Confirm the instance appears in the Review targets section at the bottom with port 80.
  • Click Create target group.

Now switch back to the ALB creation tab in your browser to finish the load balancer setup.

  • Click the refresh icon next to the Default action dropdown in the Listeners and routing section.
  • Select AppTier-TG from the dropdown.
  • Scroll to the bottom and click Create load balancer.

You should see a success banner confirming the ALB was created. The ALB takes a few minutes to become active.

  • Click View load balancer or navigate back to the Load Balancers list.
  • Wait until the State column changes from Provisioning to Active. This typically takes 2-3 minutes.

ALB stuck in Provisioning?

Give it up to 5 minutes. If it stays in Provisioning longer than that, check that you selected both public subnets (Public-Web-1a and Public-Web-1b) and that both subnets are in different Availability Zones.

help me troubleshoot my ALB staying in Provisioning state

  • Once the ALB is active, click on Target groups in the left sidebar under Load Balancing.
  • Click AppTier-TG to open it.
  • In the Targets tab, confirm your EC2 instance shows a Health status of healthy.

What if the target shows "initial" or "unhealthy"?

When first registered, targets start in an "initial" state while the ALB runs its first health check. Wait 30-60 seconds and refresh the page. If the target becomes "unhealthy", verify that your EC2 instance is still running and that Apache is serving a page on port 80.

Test the complete architecture

Everything is wired up. Time to prove the full traffic path works: internet to ALB to EC2, with the database reachable from EC2.

  • Navigate back to Load Balancers in the left sidebar.
  • Select ThreeTier-ALB.
  • In the Description section, find the DNS name field and copy its value.
  • Open a new browser tab and paste the ALB DNS name into the address bar.
  • Press Enter.

You should see "Hello from the App Tier - AZ-a" along with the instance ID. This confirms that internet traffic reached the ALB, the ALB forwarded it to your EC2 instance through the security group chain, and Apache served the response.

What does this prove about the architecture?

The full traffic flow is: Internet -> ALB (in public subnets, using Web-Tier-SG) -> EC2 (using App-Tier-SG, which only accepts traffic from Web-Tier-SG) -> RDS (using Data-Tier-SG, which only accepts traffic from App-Tier-SG).

Each tier only talks to its immediate neighbor. No component can be reached by skipping a tier. This is the defense-in-depth pattern that interviewers expect you to explain.

Now verify that the security group isolation is still working correctly.

  • Return to the EC2 Console and select your running instance.
  • Copy the instance's Public IPv4 address from the Details tab.
  • Open a new browser tab and paste the public IP address (with http:// in front of it) into the address bar.
  • Press Enter and wait.

The page should time out and never load. This is the correct behavior. App-Tier-SG only allows inbound HTTP from Web-Tier-SG, so your browser (coming from the public internet directly) is blocked.

This timeout is your proof

The fact that the ALB DNS name works but the direct EC2 IP does not is the strongest demonstration of security group isolation. The same EC2 instance, the same port, the same page. The only difference is whether traffic arrives via the ALB (carrying Web-Tier-SG) or directly from the internet.

Page loads when hitting EC2 directly?

If you can access the EC2 public IP directly, your App-Tier-SG has an incorrect inbound rule. Check that the HTTP rule's source is the Web-Tier-SG security group ID, not 0.0.0.0/0. A CIDR source of 0.0.0.0/0 would allow all traffic, breaking your isolation.

help me fix my App-Tier security group that is allowing direct public access

Your 3-tier VPC architecture is fully operational. Traffic flows through the ALB, the security groups enforce strict tier-to-tier communication, and no component is directly exposed to the internet except the load balancer. Next up, the Secret Mission challenges you to add high availability to this setup.

Secret mission

Add High Availability to the App Tier

Your architecture works, but it has a single point of failure. If your one EC2 instance goes down, the entire application is offline. Can you add a second instance in a different Availability Zone and prove the ALB keeps traffic flowing even when one instance fails?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. Public IPv4 addresses cost $0.005/hour each, so even Free Tier eligible resources will accumulate a small charge while running.

Cost warning

Your project uses public IPv4 addresses (on the ALB and EC2 instances), which cost $0.005/hour per address regardless of Free Tier status. The ALB, EC2 instances, and RDS instance are Free Tier eligible for legacy accounts (created before July 15, 2025) or covered by the $200 credits for newer accounts. If you are done with this project, delete all resources to avoid any charges.

Resources you used:

  • Application Load Balancer (ThreeTier-ALB).
  • Target Group (AppTier-TG).
  • 2 EC2 instances (App-Tier-EC2-AZ-a and App-Tier-EC2-AZ-b).
  • RDS MySQL instance (threetier-db).
  • DB Subnet Group (threetier-db-subnet-group).
  • VPC (ThreeTierVPC) with 6 subnets, Internet Gateway, route tables, and security groups.

Keep everything running

No action needed. Choose this if you are still actively building or exploring your architecture.

  • Monitor your costs in the AWS Billing Console.
  • EC2 instances (t2.micro/t3.micro) and RDS (db.t3.micro) are Free Tier eligible for 12 months on legacy accounts, or covered by the $200 credits on newer accounts.
  • Public IPv4 addresses will incur $0.005/hour per address. With 3 addresses (ALB uses 2, EC2 uses 1 each), expect roughly $0.04/hour total.

Pause - I'll come back to this later

Shut down running compute to reduce costs while keeping your network architecture intact.

  • In the EC2 Console, select both EC2 instances, choose Instance State, then Stop instance.
  • In the RDS Console, select threetier-db, choose Actions, then Stop temporarily. RDS will auto-restart after 7 days if not manually restarted.
  • Note that RDS storage charges (20 GB gp2) still apply while stopped. Public IPv4 charges also continue for any allocated addresses.
  • Your VPC, subnets, security groups, ALB, and target group remain in place for when you return.

Delete - I don't want to use this again

Remove all project resources permanently. Delete in this order to avoid dependency errors.

Step 1: Delete the Application Load Balancer.

  • Open the EC2 Console and select Load Balancers in the left navigation pane.
  • Select ThreeTier-ALB, choose Actions, then Delete load balancer.
  • Type confirm when prompted and choose Delete.

Step 2: Delete the Target Group.

  • In the EC2 Console, select Target Groups in the left navigation pane.
  • Select AppTier-TG, choose Actions, then Delete.
  • Confirm the deletion.

Step 3: Terminate the EC2 instances.

  • In the EC2 Console, select Instances in the left navigation pane.
  • Select both App-Tier-EC2-AZ-a and App-Tier-EC2-AZ-b.
  • Choose Instance State, then Terminate instance.
  • Confirm the termination. Wait for both instances to show a Terminated state before proceeding.

Step 4: Delete the RDS instance.

  • Open the RDS Console and select Databases in the left navigation pane.
  • Select threetier-db, choose Actions, then Delete.
  • Uncheck Create final snapshot (you do not need a backup of this learning project).
  • Check the acknowledgment box, type delete me in the confirmation field, and choose Delete.
  • Wait for the RDS instance to finish deleting. This can take several minutes.

Step 5: Delete the DB Subnet Group.

  • In the RDS Console, select Subnet groups in the left navigation pane.
  • Select threetier-db-subnet-group and choose Delete.
  • Confirm the deletion.

Step 6: Delete the VPC and all remaining components.

  • Open the VPC Console and select Your VPCs in the left navigation pane.
  • Select ThreeTierVPC, choose Actions, then Delete VPC.
  • The console will display all remaining components that will be deleted with the VPC (subnets, route tables, Internet Gateway, and security groups). Review the list.
  • Type delete in the confirmation field and choose Delete.

Why delete in this order?

AWS prevents you from deleting a VPC while it still has active resources like load balancers, EC2 instances, or RDS databases. By deleting the ALB, EC2, and RDS first, you remove the dependencies that would block VPC deletion.

Nice Work!

Nice Work!

You just built a production-style 3-tier VPC architecture on AWS. This is the exact network design that cloud engineering interviewers ask about, and now you have hands-on proof you can design and deploy it.

Here's what you learned:

  • Built a custom VPC with 6 subnets across 2 Availability Zones, an Internet Gateway, and route tables separating public from private traffic.
  • Created security groups enforcing strict tier-to-tier communication using security group references, proving that no direct public access can reach the app or data tier.
  • Deployed a complete 3-tier application with an Application Load Balancer routing internet traffic to an EC2 instance running Apache, connected to an RDS MySQL database in isolated private subnets.
  • Secret Mission: Added high availability by deploying a second EC2 instance in a different AZ and verified the ALB distributes traffic across both.

Ready to quiz yourself?