Build a 3-Tier VPC Architecture

Design a production-grade VPC with isolated web, app, and database tiers.

Introduction

30 Second Summary

Think about how a bank is designed. Customers walk into the lobby, but only employees can access the back office, and the vault is locked behind even more security.

In this project, you will build a 3-tier network architecture on AWS that isolates web servers, application servers, and databases into separate network layers with strict access controls between them.

What You'll Build

You'll SSH into a web server, hop to the app tier, then watch a connection attempt to the database tier get blocked in real time, proving your network isolation works.

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

  • A VPC with 6 subnets across 2 Availability Zones, giving your architecture built-in fault tolerance.
  • A running web server in the public tier that you can reach from your browser and see a live page.
  • Security group chaining that enforces adjacent-only communication, so the web tier cannot bypass the app tier to reach the database directly.
  • Secret Mission: Add Network ACLs as a second layer of defense with explicit deny rules between non-adjacent tiers.

Are there any prerequisites?

You need an AWS account with console access. All work in this project is done through the AWS Management Console in your browser.

Before We Start

Before we dive in, let's lock in what you're about to build and why it matters. In production, you never put your database on the same network as your public-facing web server. A 3-tier VPC is the standard pattern for isolating sensitive resources behind multiple layers of network controls.

Create the VPC with Public and Private Subnets

Before you can launch servers or configure security rules, you need a network to put them in. In AWS, this network is a VPC (Virtual Private Cloud). It defines an isolated address space where all your resources will live.

In this step, you'll use the "VPC and more" wizard to create a VPC with public and private subnets, an Internet Gateway, a NAT Gateway, and route tables in one shot. Then you'll manually add dedicated database subnets to complete the 3-tier foundation.

In this step, get ready to:
  • Create a VPC with public and private subnets using the "VPC and more" wizard.
  • Add dedicated database subnets for the third tier.
  • Verify the full architecture in the Resource map.
Create VPC using "VPC and more"

The "VPC and more" wizard creates an entire network foundation in one operation. It handles the VPC, subnets, gateways, and route tables so you don't have to wire each one up individually.

  • In the AWS Management Console, navigate to the VPC console by entering this URL in your browser:
  • https://console.aws.amazon.com/vpc/
  • On the VPC dashboard, click Create VPC.
  • For Resources to create, choose VPC and more.
  • For Name tag auto-generation, enter three-tier.
  • For IPv4 CIDR block, enter 10.0.0.0/16.
  • For Number of Availability Zones, choose 2.
  • For Number of public subnets, choose 2.
  • For Number of private subnets, choose 2.
  • For NAT gateways, choose In 1 AZ.
  • For VPC endpoints, choose None.
  • Click Create VPC.

The wizard takes a moment to create all the resources. You'll see a progress page listing each resource as it's created.

What did the wizard just create?

In one operation, the wizard created all of these resources:

  • A VPC named three-tier-vpc with the CIDR range 10.0.0.0/16 (65,536 IP addresses).
  • 2 public subnets and 2 private subnets across 2 Availability Zones.
  • An Internet Gateway attached to the VPC for public internet access.
  • A NAT Gateway in one public subnet so private instances can reach the internet without being directly exposed.
  • Route tables wired up: public subnets route to the Internet Gateway, private subnets route to the NAT Gateway.

Why "In 1 AZ" for the NAT Gateway?

NAT Gateways cost $0.045 per hour. For a learning project, one NAT Gateway keeps costs minimal. In production, you'd deploy one per Availability Zone for high availability.

  • Once creation completes, click View VPC to see your new VPC.

You should see three-tier-vpc listed with the CIDR 10.0.0.0/16 and state Available.

Don't see your VPC?

  • Make sure you're in the correct AWS Region. Check the Region selector in the top-right corner of the console.
  • If the creation failed, check for a CIDR conflict with an existing VPC using the same range.
  • help me troubleshoot why my VPC creation failed
Add dedicated database subnets

The wizard only creates one set of private subnets. A true 3-tier architecture needs a separate set of subnets dedicated to the database tier. You'll create these manually now.

  • In the VPC console navigation pane, choose Subnets.
  • Click Create subnet.
  • For VPC ID, select three-tier-vpc.
  • Under the first subnet settings, for Subnet name, enter three-tier-db-subnet-1.
  • For Availability Zone, select the first AZ (the same one used by your other subnets, e.g. us-east-1a).
  • For IPv4 subnet CIDR block, enter 10.0.128.0/24.
  • Click Add new subnet at the bottom of the page.
  • For Subnet name, enter three-tier-db-subnet-2.
  • For Availability Zone, select the second AZ (e.g. us-east-1b).
  • For IPv4 subnet CIDR block, enter 10.0.144.0/24.
  • Click Create subnet.

You should see both three-tier-db-subnet-1 and three-tier-db-subnet-2 appear in your subnet list.

Why separate database subnets?

Putting the database tier in its own subnets lets you apply different route table rules and security controls to database resources. This is the foundation of network isolation. Web servers live in public subnets, app servers in one set of private subnets, and databases in another.

Now you need to associate these new DB subnets with the private route table (the one that routes through the NAT Gateway) so they have outbound internet access for updates.

  • In the VPC console navigation pane, choose Route tables.
  • Find the private route table. It will have a name like three-tier-rtb-private and its Routes tab will show a route with a NAT Gateway as the target.
  • Select that route table.
  • Choose the Subnet associations tab.
  • Click Edit subnet associations.
  • Select the checkboxes for both three-tier-db-subnet-1 and three-tier-db-subnet-2.
  • Click Save associations.

The Explicit subnet associations section now shows both DB subnets alongside your existing private app subnets.

Don't see your DB subnets in the list?

  • Make sure you selected three-tier-vpc when creating the subnets. Subnets created in a different VPC won't appear here.
  • If the CIDR block was rejected, check that 10.0.128.0/24 and 10.0.144.0/24 don't overlap with any existing subnets in your VPC.
  • help me fix my database subnet creation in the VPC
Verify the architecture in the Resource map

Before you think about what you expect to see, consider the full picture: you've got a VPC, 6 subnets across 2 tiers of privacy, an Internet Gateway, a NAT Gateway, and route tables connecting them all.

  • In the VPC console navigation pane, choose Your VPCs.
  • Select three-tier-vpc.
  • Choose the Resource map tab.
  • Click Show details to reveal CIDR ranges and route table associations.

What do you expect to see in the Resource map? Take a moment to predict before you look.

You should see all of the following in the visualization:

  • 2 public subnets (shown in green) associated with a route table that routes to the Internet Gateway.
  • 4 private subnets (shown in blue): 2 app subnets and 2 DB subnets, all associated with a route table that routes to the NAT Gateway.
  • An Internet Gateway connected to the VPC.
  • A NAT Gateway in one of the public subnets.

What am I looking at?

The Resource map shows how traffic flows through your VPC. Solid lines represent resource relationships (subnets belonging to route tables). Dotted lines represent network traffic paths (subnets routing through gateways).

Public subnets route to the Internet Gateway for direct internet access. Private subnets route to the NAT Gateway for outbound-only internet access. This is the foundation that makes the web tier publicly reachable and keeps the app and database tiers hidden.

Your network foundation is complete. You have a fully wired VPC with public, private app, and private database subnets spanning two Availability Zones. Next up, you'll launch a web server in the public tier and prove it's accessible from the internet.

Launch a Web Server in the Public Tier

Your VPC foundation is solid. You have public subnets routed to the Internet Gateway, private subnets routing through the NAT Gateway, and dedicated database subnets ready for isolation.

Now you need proof that this infrastructure actually works. Launching a web server in the public tier and loading its page in a browser proves your subnet, Internet Gateway, and routing are all wired correctly.

In this step, get ready to:
  • Launch an EC2 instance in the public subnet with a web server.
  • Configure a security group to allow web traffic.
  • Verify the web page is accessible from the internet.
Launch an EC2 instance in the public subnet

An EC2 instance is a virtual server that runs in your VPC. You will place one in the public subnet and install a web server on it so you can see a live page from your browser.

  • In the AWS Console search bar at the top, type EC2.
  • Select EC2 from the results to open the EC2 console.
  • Click Launch instance.
  • For Name, enter web-tier-instance.
  • Under Application and OS Images, select Amazon Linux (it is marked Free tier eligible).
  • For Instance type, select t2.micro (Free tier eligible).
  • For Key pair, select an existing key pair or click Create new key pair to create one.

Why do I need a key pair?

A key pair gives you SSH access to your instance. You will use it later to log in from your terminal and test connectivity between tiers.

If you create a new key pair, choose the .pem format and save the downloaded file somewhere you can find it. You will need it in later steps.

  • Under Network settings, click Edit.
  • For VPC, select three-tier-vpc.
  • For Subnet, select three-tier-subnet-public1.
  • For Auto-assign public IP, select Enable.
  • Under Firewall (security groups), select Create security group.
  • For Security group name, enter web-tier-sg.
  • Confirm the first inbound rule is Type ssh, Port 22, Source type My IP.
  • Click Add security group rule to add a second rule.
  • Set the second rule's Type to HTTP (port 80), and Source to Anywhere (0.0.0.0/0).

What do these security group rules do?

A security group acts as a virtual firewall for your instance. Each inbound rule defines what traffic is allowed in.

The SSH rule lets only your computer connect on port 22 for terminal access. The HTTP rule lets anyone on the internet reach port 80, which is where your web server will respond.

  • Scroll down and expand the Advanced details section.
  • Scroll to the User data field at the bottom.
  • 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>Web Tier - 3-Tier VPC Architecture</h1>" > /var/www/html/index.html

What does this script do?

User data runs automatically when the instance first boots. This script does three things:

  • Updates the system packages and installs Apache (httpd), a web server that listens on port 80.
  • Starts Apache and enables it so it survives reboots.
  • Creates a simple HTML page that proves this instance belongs to the web tier.
  • Click Launch instance.

You should see a success message confirming the instance is launching. Click the instance ID link to navigate to the Instances page.

Wait for the Running state

The instance takes 1-2 minutes to move from Pending to Running. Wait until the Instance state column shows Running and Status check shows 2/2 checks passed before testing.

Test web access

Your instance is running and Apache is serving a page on port 80. The public IP, the Internet Gateway, and your route table should deliver that page to your browser.

  • On the Instances page, select web-tier-instance.
  • In the instance details pane below, find and copy the Public IPv4 address.

Before you open the address, predict what you expect to see. Will the page load successfully, or will the connection time out?

  • Open a new browser tab and navigate to http:// followed by the public IP address you copied.

You should see a page displaying "Web Tier - 3-Tier VPC Architecture" in large text. This confirms your public subnet, Internet Gateway, route table, and security group are all working together.

Page not loading?

  • Make sure you are using http:// not https:// in the URL. Apache is only serving on plain HTTP.
  • Check that Auto-assign public IP was set to Enable. If the Public IPv4 address field is empty, the instance has no public IP.
  • Verify that web-tier-sg has an inbound HTTP rule with source 0.0.0.0/0. Without it, port 80 is blocked.
  • Wait 2-3 minutes after the instance enters Running state. The user data script needs time to install and start Apache.

Still stuck? Help me troubleshoot why my EC2 web server page is not loading.

Your web tier is live and reachable from the internet. Next, you will launch an instance in the private tier and discover what happens when there is no real isolation between tiers.

Launch an App Tier Instance and Discover the Isolation Problem

Your web server is live and reachable from the internet. The next layer in a production 3-tier architecture is the application tier, where business logic runs in a private subnet away from public traffic.

But does putting instances in separate subnets actually isolate them from each other? In this step, you'll launch an app tier instance and test whether the web tier can reach it directly. The answer might surprise you.

In this step, get ready to:
  • Launch an EC2 instance in the private app subnet.
  • SSH hop from the web tier to the app tier.
  • Discover that your tiers have no real network isolation yet.
Launch an app tier instance

The app tier sits in a private subnet with no public IP. It should only be reachable from within the VPC, not from the internet.

  • Return to the EC2 console.
  • Click Launch instance.
  • For Name, enter app-tier-instance.
  • For AMI, select Amazon Linux (Free tier eligible).
  • For Instance type, select t2.micro (Free tier eligible).
  • For Key pair, select the same key pair you used for the web tier instance.

Now configure the network settings to place this instance in the private app subnet.

  • Under Network settings, click Edit.
  • For VPC, select three-tier-vpc.
  • For Subnet, select three-tier-subnet-private1 (your first private subnet).
  • For Auto-assign public IP, select Disable.
  • For Firewall (security groups), select Create security group.
  • For Security group name, enter app-tier-sg.
  • For Description, enter App tier security group.

Now configure the inbound rules. You'll allow SSH and application traffic from the entire VPC CIDR range.

  • For the first inbound rule, set Type to SSH (port 22) and Source to 10.0.0.0/16 (the entire VPC CIDR).
  • Click Add security group rule.
  • For the second rule, set Type to Custom TCP, Port range to 8080, and Source to 10.0.0.0/16.
  • Click Launch instance.

You should see a success message confirming your instance is launching. Wait 1-2 minutes for the instance state to show Running in the EC2 console.

Why no public IP?

The app tier sits in a private subnet. It has no public IP and no direct route to the internet. The only way to reach it is through another instance inside the VPC.

Outbound internet access (for updates, API calls) still works through the NAT Gateway you set up earlier.

  • Once the instance shows Running, select app-tier-instance and note its Private IPv4 address from the details panel. You will need this for the SSH hop.

Instance stuck in Pending?

Give it up to 2 minutes. If it stays in Pending longer, check that you selected a subnet inside three-tier-vpc and not the default VPC.

Help me troubleshoot my app tier instance

SSH hop from web tier to app tier

The app tier has no public IP, so you cannot SSH to it directly from your laptop. You need to hop through the web tier instance first.

To avoid copying your private key onto the web instance (a security risk), you will use SSH agent forwarding. This passes your key's authentication through the connection without storing the key on the intermediate server.

  • First, add your key to your local SSH agent by running this in your local terminal:
ssh-add [[PEMPATH="path to your .pem key file"]]

What does ssh-add do?

This loads your private key into your local SSH agent's memory. When you connect to the web tier with the -A flag, the agent forwards your key's authentication to the next hop without ever placing the key file on the remote server.

  • SSH into the web tier instance with agent forwarding enabled by running:
ssh -A -i [[PEMPATH="path to your .pem key file"]] ec2-user@[[WEB_PUBLIC_IP="your web tier public IPv4 address"]]

You should see the Amazon Linux prompt, confirming you are on the web tier instance.

Now for the real test. You are about to try SSHing from the web tier directly to the app tier using the app tier's private IP address.

Before you run this, think: in a properly isolated 3-tier architecture, should the web tier be able to SSH directly into the app tier?

  • From the web tier instance, SSH to the app tier by running:
ssh ec2-user@[[APP_PRIVATE_IP="your app tier private IPv4 address"]]

It works. You land on the app tier instance's Amazon Linux prompt. The web tier can reach the app tier with no resistance at all.

Connection timed out or refused?

If you see a timeout, confirm that the app-tier-sg inbound rule allows SSH from 10.0.0.0/16. Also confirm you used the app tier's private IP (not a public IP, which it doesn't have).

If you see "Permission denied", your SSH agent forwarding may not be working. Make sure you used the -A flag when connecting to the web tier and that you ran ssh-add with your key file first.

Help me troubleshoot my SSH hop

Observe the isolation problem

That SSH hop succeeded. That is the problem.

Look at the inbound rules you set on app-tier-sg. They allow SSH and port 8080 from 10.0.0.0/16. That is your entire VPC CIDR range. It means any instance in the VPC can reach the app tier. The web tier, the database tier, a rogue instance someone launches in any subnet. All of them can connect.

Why is this dangerous?

If an attacker compromises your public-facing web server, they can move laterally to the app tier. From there, they could reach the database tier too. There is zero tier isolation despite the subnets being separate.

Separate subnets give you separate routing, not separate access control. Security groups are what enforce who can talk to whom. Right now, yours are too permissive.

  • Type exit to leave the app tier instance.
  • Type exit again to leave the web tier instance and return to your local machine.

You have proven the gap. Your subnets are separate, but your security groups allow any instance in the VPC to reach the app tier. In the next step, you will fix this by replacing the broad CIDR rules with security group referencing, so only adjacent tiers can communicate.

Implement Security Group Chaining for Tier Isolation

In the previous step, you proved that the app tier is wide open to any instance in your VPC. Despite living in separate subnets, the broad CIDR-based rules (10.0.0.0/16) mean a compromised web server could hop to any tier.

The fix is security group referencing. Instead of allowing traffic from an IP range, you specify a security group as the source. Only instances attached to that source security group can connect. This creates a chain: web-tier-sg talks to app-tier-sg, app-tier-sg talks to db-tier-sg, and web-tier-sg cannot reach db-tier-sg.

In this step, get ready to:
  • Create a DB tier security group that only accepts traffic from the app tier security group.
  • Update the app tier security group to only accept traffic from the web tier security group.
  • Launch a DB tier instance and prove that network isolation works.
Create the DB tier security group with SG referencing

Security group referencing means you select a security group ID as the traffic source instead of a CIDR range. Only instances attached to the referenced security group can reach your resource.

  • Return to the VPC console at https://console.aws.amazon.com/vpc/.
  • In the left navigation, click Security groups.
  • Click Create security group.
  • For Security group name, enter db-tier-sg.
  • For Description, enter Database tier - only accessible from app tier.
  • For VPC, remove the default VPC and select three-tier-vpc.

Now add the inbound rules that reference app-tier-sg as the source.

  • Under Inbound rules, click Add rule.
  • For the first rule, set Type to MySQL/Aurora (this auto-fills port 3306).
  • For Source, click the search field and type app-tier-sg. Select the app-tier-sg security group from the dropdown.
  • Click Add rule again.
  • For the second rule, set Type to SSH (port 22).
  • For Source, search for and select app-tier-sg again.
  • Click Create security group.

You should see a success banner confirming that db-tier-sg was created. The inbound rules summary shows both rules referencing app-tier-sg instead of an IP range.

Why reference a security group instead of an IP range?

When you specify a security group as the source, AWS dynamically evaluates which instances belong to that group. If you add or remove app servers later, the DB rules automatically adapt. No manual IP updates needed.

A CIDR rule like 10.0.0.0/16 allows the entire VPC. A security group reference narrows access to only the instances wearing that specific security group.

Don't see app-tier-sg in the source dropdown?

Make sure you selected three-tier-vpc as the VPC for this new security group. Security groups can only reference other groups in the same VPC.

If the VPC field still shows the default VPC, clear it and search for three-tier-vpc. help me find the right VPC for my security group

Update the app tier security group to reference web-tier-sg

The app tier currently allows SSH and port 8080 from the entire VPC CIDR. You need to tighten it so only the web tier can reach it.

  • In the Security groups list, click on app-tier-sg to open it.
  • Click the Inbound rules tab.
  • Click Edit inbound rules.
  • Delete both existing rules by clicking the Delete button next to each one (the rules referencing 10.0.0.0/16).
  • Click Add rule. Set Type to SSH (port 22). For Source, search for and select web-tier-sg.
  • Click Add rule again. Set Type to Custom TCP, set Port range to 8080. For Source, select web-tier-sg.
  • Click Save rules.

You should see a success banner. The inbound rules now show web-tier-sg as the source for both rules instead of the broad CIDR.

What did you just build?

You now have a security group chain. web-tier-sg is allowed into app-tier-sg, and app-tier-sg is allowed into db-tier-sg. Because web-tier-sg is NOT listed as a source in db-tier-sg, the web tier cannot reach the database tier directly.

Launch a DB tier instance and test isolation

The security groups are configured. Now you need an actual instance in the database tier to prove the chain works.

  • Open the EC2 console and click Launch instance.
  • For Name, enter db-tier-instance.
  • For AMI, select Amazon Linux (Free tier eligible).
  • For Instance type, select t2.micro (Free tier eligible).
  • For Key pair, select the same key pair you used for your other instances.
  • Click Edit under Network settings.
  • For VPC, select three-tier-vpc.
  • For Subnet, select three-tier-db-subnet-1.
  • For Auto-assign public IP, select Disable.
  • For Firewall (security groups), choose Select existing security group.
  • Select db-tier-sg from the list.
  • Click Launch instance.
  • Wait for the instance state to show Running in the EC2 instances list.
  • Note the Private IPv4 address of db-tier-instance. You will need this for the connectivity test.

Now it is time to prove that security group chaining actually blocks cross-tier traffic. You will first install a network testing tool, then attempt to reach the database port from two different locations.

  • SSH into your web tier instance using SSH agent forwarding by running this command on your local machine:
ssh -A -i [[PEMPATH="path/to/your-key.pem"]] ec2-user@[[WEB_PUBLIC_IP="your web-tier-instance public IP"]]

What does the -A flag do?

The -A flag enables SSH agent forwarding. This lets you hop from the web tier to the app tier using your local key without copying the private key onto the web instance. It is a security best practice for multi-hop SSH.

  • Once connected to the web tier instance, install the network connectivity tool by running:
sudo yum install -y nmap-ncat

Before you test, think about what you expect to happen. The web tier instance is wearing web-tier-sg. The DB instance is protected by db-tier-sg, which only allows inbound from app-tier-sg. Do you think the web tier can reach port 3306 on the DB instance?

  • Test the connection from the web tier to the DB tier by running:
nc -zv [[DB_PRIVATE_IP="your db-tier-instance private IP"]] 3306 -w 5

The command hangs for 5 seconds and then reports a timeout or connection refused. The web tier CANNOT reach the database tier on port 3306. This is your security group chain at work.

What does this nc command do?

The nc command (netcat) tests TCP connectivity. The -z flag means scan mode (connect and disconnect without sending data). The -v flag enables verbose output so you see the result. The -w 5 flag sets a 5-second timeout so you do not wait forever.

Now test from the app tier, which SHOULD have access.

  • From the web tier instance, SSH hop to the app tier instance:
ssh ec2-user@[[APP_PRIVATE_IP="your app-tier-instance private IP"]]
  • On the app tier instance, install the same network tool:
sudo yum install -y nmap-ncat
  • Test the connection from the app tier to the DB tier:
nc -zv [[DB_PRIVATE_IP="your db-tier-instance private IP"]] 3306 -w 5

This time the connection succeeds immediately. The app tier CAN reach the database tier on port 3306 because app-tier-sg is listed as the allowed source in db-tier-sg.

What just happened?

You proved that security group chaining enforces adjacent-only communication. The web tier can reach the app tier (allowed by app-tier-sg), and the app tier can reach the database tier (allowed by db-tier-sg). But the web tier cannot skip a tier and reach the database directly.

Even though all three instances live in the same VPC, the security group references create a strict communication path. A compromised web server cannot move laterally to the database.

Connection from web tier succeeded instead of timing out?

Double-check the inbound rules on db-tier-sg. Both rules should show app-tier-sg as the source, not a CIDR range like 10.0.0.0/16. If you accidentally selected a CIDR, edit the rules and change the source to the security group.

Also verify that db-tier-instance is assigned db-tier-sg and not a different security group. Check this in the EC2 console under the instance's Security tab. help me troubleshoot why my web tier can reach the DB tier

nc command not found?

The nc command is not installed by default on Amazon Linux. Make sure you ran sudo yum install -y nmap-ncat on the instance where you are testing. You need to install it on both the web tier and the app tier instances separately.

If the install fails, confirm the instance has outbound internet access (the private subnets route through the NAT Gateway). help me install nc on my EC2 instance

Tier isolation is proven. Your 3-tier VPC now enforces strict adjacent-only communication through security group chaining. A request must pass through each tier in sequence to reach the database.

Secret mission

Add Network ACLs as a Second Defense Layer

Your security groups enforce tier isolation at the instance level. But what if someone accidentally opens a security group rule? Network ACLs add a second wall at the subnet level. In this mission, you'll create explicit DENY rules that block the public tier from ever reaching the database subnets, regardless of security group configuration.

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. The NAT Gateway costs $0.045 per hour while provisioned, so leaving everything running will incur charges.

Cost warning

The NAT Gateway costs $0.045/hour. If you leave it running for 24 hours, that is approximately $1.08. The EC2 instances are t2.micro (free tier eligible), but the NAT Gateway is not covered by the free tier.

If you are not continuing immediately, choose Pause or Delete below to stop charges.

Resources you used:

  • 1 VPC (three-tier-vpc) with 6 subnets across 2 Availability Zones.
  • 1 Internet Gateway attached to the VPC.
  • 1 NAT Gateway in a public subnet.
  • 3 EC2 instances (web-tier-instance, app-tier-instance, db-tier-instance).
  • 3 Security Groups (web-tier-sg, app-tier-sg, db-tier-sg).
  • Route tables (public and private).
  • 1 custom Network ACL (db-nacl) if you completed the Secret Mission.

Keep everything running

No action needed. Choose this if you are still actively building or plan to experiment with the architecture immediately.

  • Your 3-tier VPC and all resources remain active.
  • The NAT Gateway will continue to charge $0.045/hour.
  • EC2 instances remain running (free tier eligible for t2.micro within the first 12 months).

Pause - I'll come back to this later

Terminate the EC2 instances and delete the NAT Gateway to stop charges, but keep the VPC structure intact so you can relaunch instances later.

  • Open the EC2 console at https://console.aws.amazon.com/ec2/.
  • In the navigation pane, choose Instances.
  • Select all three instances (web-tier-instance, app-tier-instance, db-tier-instance).
  • Choose Instance state, then Terminate (delete) instance.
  • Choose Terminate (delete) when prompted for confirmation.
  • Open the VPC console at https://console.aws.amazon.com/vpc/.
  • In the navigation pane, choose NAT gateways.
  • Select your NAT Gateway, choose Actions, then Delete NAT gateway.
  • Type delete to confirm and choose Delete.

Your VPC, subnets, route tables, security groups, and Network ACL remain in place at no cost. You can launch new instances into the same architecture when you return.

Delete - I don't want to use this again

Remove all project resources completely. This is the recommended option to avoid any ongoing charges.

First, terminate all EC2 instances:

  • Open the EC2 console at https://console.aws.amazon.com/ec2/.
  • In the navigation pane, choose Instances.
  • Select all three instances (web-tier-instance, app-tier-instance, db-tier-instance).
  • Choose Instance state, then Terminate (delete) instance.
  • Choose Terminate (delete) when prompted for confirmation.
  • Wait for the instances to show a terminated state before continuing.

Next, delete the NAT Gateway:

  • Open the VPC console at https://console.aws.amazon.com/vpc/.
  • In the navigation pane, choose NAT gateways.
  • Select your NAT Gateway, choose Actions, then Delete NAT gateway.
  • Type delete to confirm and choose Delete.
  • Wait approximately 1-2 minutes for the NAT Gateway to reach the deleted state.

Finally, delete the VPC (this removes all remaining associated resources):

  • In the VPC console navigation pane, choose Your VPCs.
  • Select three-tier-vpc.
  • Choose Actions, then Delete VPC.
  • Review the list of resources that will be deleted. This includes all subnets, route tables, the Internet Gateway, Network ACLs, and security groups.
  • Type delete to confirm and choose Delete.

What does Delete VPC remove?

When you delete a VPC through the console, AWS also deletes the associated subnets, route tables, Internet Gateway, Network ACLs, and security groups. You must terminate EC2 instances and delete the NAT Gateway yourself before this step.

That's a Wrap!

That's a Wrap!

Nice work! You just built a production-grade 3-tier network architecture on AWS, complete with strict tier isolation that you proved works by testing real traffic between layers.

You've learned how to:

  • Build a 3-tier VPC with public, private application, and private database subnets spanning 2 Availability Zones, wired up with an Internet Gateway for public access and a NAT Gateway for private outbound connectivity.
  • Implement security group chaining where each tier only accepts traffic from its adjacent tier, replacing broad CIDR-based rules with precise security group references.
  • Prove network isolation works by SSHing between tiers and watching the web tier's connection to the database tier time out.
  • Secret Mission: Added Network ACLs as a defense-in-depth measure at the subnet level, enforcing explicit deny rules that block cross-tier traffic regardless of security group configuration.

Ready to quiz yourself?