Build a Production-Style VPC on AWS

Build a custom VPC with public and private subnets and prove network isolation.

Introduction

30 Second Summary

Every app you use online sits behind a network that decides what traffic gets in and what stays out. On AWS, that network is called a Virtual Private Cloud (VPC). Designing one is the foundational skill behind every production architecture.

In this project, you will build a custom VPC on AWS with a public subnet and a private subnet. You will launch EC2 instances in each subnet, then prove that your network design enforces real isolation.

What You'll Build

Picture running the exact same command on two servers in the same cloud network, and watching one respond instantly while the other times out.

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

  • A custom VPC with a public subnet that routes traffic through an internet gateway and a private subnet that blocks all internet access.
  • Two EC2 instances you can connect to and test side by side. One reaches the internet instantly. The other times out, proving your network boundaries are real.
  • A secure tunnel into the private instance using an EC2 Instance Connect Endpoint. No bastion host, no public IP, no key pair to manage.
  • Secret Mission: Add a NAT gateway so your private instances can reach the internet for software updates. Create a second private subnet in a different Availability Zone for high availability.

Do I need any AWS experience?

You need an AWS account with free tier eligibility and a web browser. No prior networking experience is required.

Before We Start

Before we dive in, let's lock in what you're about to build and why it matters.

Create Your Custom VPC with Subnets

Every AWS account comes with a default VPC. It is a flat network where every resource sits in the same space with no separation between public-facing servers and internal ones. For any production architecture, that is not enough.

You need a custom VPC to control how traffic flows between different parts of your network. In this step, you will create one with a public subnet and a private subnet, each with its own routing rules.

In this step, get ready to:
  • Create a custom VPC with public and private subnets using the AWS VPC console.
  • Examine the route tables and internet gateway that AWS creates automatically.
  • Confirm that the public and private subnets have different routing configurations.
Open the VPC console and create your VPC

AWS offers a VPC and more wizard that creates the VPC, subnets, route tables, and internet gateway all in a single operation. This saves you from manually wiring up each resource individually.

  • Sign in to the AWS Management Console.
  • In the search bar at the top of the console, type VPC.
  • Select VPC from the search results to open the VPC console.
  • Click Create VPC.
  • Under Resources to create, select VPC and more.
  • Under Name tag auto-generation, enter my-vpc.
  • For IPv4 CIDR block, enter 10.0.0.0/16.

What is a CIDR block?

A CIDR block defines the range of IP addresses available inside your VPC. 10.0.0.0/16 gives you 65,536 addresses (from 10.0.0.0 to 10.0.255.255).

The /16 part means the first 16 bits of the address are fixed. The remaining bits are yours to carve into subnets. Think of it as reserving an entire apartment building, where each floor becomes a subnet.

  • For Number of Availability Zones, choose 1.
  • For Number of public subnets, choose 1.
  • For Number of private subnets, choose 1.
  • For NAT gateways, choose None.
  • For VPC endpoints, choose None.
  • Leave all other settings at their defaults.
  • Click Create VPC.

Why choose None for NAT gateways?

A NAT gateway lets private subnet resources reach the internet without being directly reachable from the outside. It costs $0.045 per hour plus $0.045 per GB of data processed.

You are skipping it intentionally to keep this project free. The whole point of the private subnet is to prove it has no internet access. You will explore NAT gateways in the Secret Mission.

AWS takes a moment to create all six resources. Wait for the green success banners to appear before continuing.

Seeing an error during VPC creation?

  • Make sure the CIDR block is exactly 10.0.0.0/16 with no extra spaces or characters.
  • Check that you selected VPC and more, not VPC only. The VPC only option creates just the VPC without subnets or route tables.
  • If your account is brand new, confirm you are in a supported AWS region by checking the region dropdown in the top-right corner of the console.

My VPC creation failed or shows an error

Explore the resources AWS created

The wizard created several resources that work together to form your network. Let's walk through each one to understand how they connect.

  • Click View VPC to open the Resource map.

The Resource map shows your VPC and all the resources inside it. You should see five resources: the VPC itself, one public subnet, one private subnet, two route tables, and one internet gateway.

What is an internet gateway?

An internet gateway is the bridge between your VPC and the public internet. Without one attached, nothing inside the VPC can send or receive traffic from the outside world.

The wizard automatically created one and attached it to your VPC. Only the public subnet will use it, though. The private subnet has no route pointing to it.

Now let's look at the route tables to understand why one subnet is "public" and the other is "private."

  • Click Route tables in the left sidebar.
  • Select the route table that has public in its name.
  • Click the Routes tab at the bottom of the page.

The public route table has two routes. The first route sends traffic destined for 10.0.0.0/16 to local, which keeps VPC-internal traffic inside the network. The second route sends 0.0.0.0/0 (all other traffic) to the internet gateway.

Before you look at the private route table, what routes do you think it has?

  • Select the route table that has private in its name.
  • Click the Routes tab.

The private route table has only one route: 10.0.0.0/16 to local. There is no route to the internet gateway. Traffic from this subnet has nowhere to go except within the VPC.

What makes a subnet public or private?

A subnet with a route to an internet gateway is a public subnet. A subnet without a route to an internet gateway is a private subnet.

The subnet itself does not "know" the difference. It is entirely determined by its associated route table. Swap the route table, and a public subnet becomes private (or vice versa).

Verify the subnet configuration

Each subnet is linked to exactly one route table. Let's confirm that the public subnet points to the public route table and the private subnet points to the private route table.

  • Click Subnets in the left sidebar.
  • Select the subnet named my-vpc-subnet-public1 (the console may append a region or Availability Zone suffix to the name).
  • On the Route table tab, confirm it is associated with the public route table (the one with a route to the internet gateway).
  • Select the subnet named my-vpc-subnet-private1.
  • On the Route table tab, confirm it is associated with the private route table (the one with only the local route and no internet gateway).

Both subnets are correctly linked to their route tables. The public subnet has a path to the internet through the internet gateway. The private subnet is completely isolated within the VPC.

Subnet showing the wrong route table?

  • Make sure you selected VPC and more when creating the VPC. Choosing VPC only skips the automatic route table and subnet association. If you used VPC only, delete the VPC and start over with VPC and more.
  • If you see more subnets or route tables than expected, you may be looking at the default VPC's resources. Filter by VPC by selecting my-vpc in the VPC filter dropdown.

My subnets or route tables don't look right

Your custom VPC is in place with clearly separated public and private subnets. Next up, you will launch an EC2 instance in the public subnet and prove that the internet gateway actually delivers internet access.

Launch an EC2 Instance in the Public Subnet

Your custom VPC is built with a public subnet, a private subnet, an internet gateway, and two route tables. But right now, the network is completely empty.

A VPC with no instances is just an empty network. In this step, you will launch your first EC2 instance in the public subnet and prove that the internet gateway and route table configuration actually works.

In this step, get ready to:
  • Launch a t2.micro EC2 instance in the public subnet with a public IP address.
  • Connect to the instance and confirm it can reach the internet.
Launch the public instance

To test your VPC, you need a server running inside it. EC2 lets you launch virtual servers (called instances) in any subnet of your VPC.

  • Navigate to the EC2 console.
  • Choose Launch instances.
  • For Name, enter public-instance.
  • For Application and OS Images (Amazon Machine Image), keep Amazon Linux 2023 AMI (free tier eligible).
  • For Instance type, keep t2.micro (free tier eligible).
  • For Key pair (login), choose Proceed without a key pair.

Why no key pair?

EC2 Instance Connect pushes a temporary SSH key every time you connect, so you do not need a persistent key pair on disk. This avoids key management headaches entirely.

Now configure the network settings to place this instance in your public subnet.

  • Under Network settings, choose Edit.
  • For VPC, select my-vpc.
  • For Subnet, select the public subnet (my-vpc-subnet-public1).
  • For Auto-assign public IP, select Enable.
  • For Firewall (security groups), choose Create security group.
  • For Security group name, enter public-sg.
  • The first inbound rule defaults to SSH. For Source type, select My IP.
  • Choose Add security group rule to add a second rule.
  • For Type on the new rule, select All ICMP - IPv4.
  • For Source type, select Anywhere (0.0.0.0/0). This allows ping from any IP address.
  • Scroll down and choose Launch instance.

What do these security group rules do?

A security group acts as a virtual firewall for your instance, controlling which traffic is allowed in and out.

  • The SSH rule (port 22) from My IP lets only your current IP address connect to the instance remotely. This follows AWS best practice of restricting SSH to specific IPs.
  • The All ICMP - IPv4 rule from 0.0.0.0/0 allows ICMP traffic (ping) from anywhere, so you can verify network connectivity.
  • Wait for the instance to reach Running state. You can choose View all instances to monitor its progress.
  • Once the instance is running, check the Public IPv4 address column. You should see an IP address assigned to your instance.

Instance stuck in Pending?

It can take 30 to 60 seconds for a new instance to reach Running state. Click the refresh icon in the instances list to check for updates. If the Public IPv4 address column shows a dash after the instance is running, go back and confirm you set Auto-assign public IP to Enable in your network settings.

Help me troubleshoot my EC2 instance launch

Connect to the public instance and test internet access

Your instance is running, but you have not yet proven that it can actually reach the internet. The route table says traffic should flow through the internet gateway. Time to test that claim.

  • Select public-instance in the instances list.
  • Choose Connect at the top of the page.
  • On the EC2 Instance Connect tab, choose Connect.

A browser-based terminal opens, connected directly to your instance. This works because the instance has a public IP and the security group allows SSH from your IP.

What is EC2 Instance Connect?

EC2 Instance Connect is a browser-based SSH client built into the AWS console. It pushes a temporary SSH key for each session, so you never need to manage key pairs on your local machine.

Before you run the next command, what do you think will happen? Your public subnet has a route to the internet gateway. Will the instance be able to reach an external website?

  • Test internet access by running this command:
curl -s -o /dev/null -w "%{http_code}" https://aws.amazon.com

You should see 200 printed in the terminal. This confirms the instance has full internet access through the internet gateway.

What does this command do?

  • curl sends an HTTP request to the specified URL.
  • -s runs in silent mode (no progress bar).
  • -o /dev/null discards the page content so you only see the status code.
  • -w "%{http_code}" prints just the HTTP status code (like 200 for success).
  • Verify ICMP traffic by running this command:
ping -c 3 8.8.8.8

You should see three successful ping responses from 8.8.8.8. This proves that both HTTP and ICMP traffic flow through the internet gateway from your public subnet.

Not seeing 200 or ping responses?

  • Make sure you launched the instance in my-vpc-subnet-public1, not the private subnet. The private subnet has no route to the internet gateway.
  • Confirm that Auto-assign public IP was set to Enable. Without a public IP, the instance cannot send or receive internet traffic.
  • Check that the public route table still has a 0.0.0.0/0 route pointing to the internet gateway. Return to the VPC console and inspect the route table associated with your public subnet.
  • Help me troubleshoot internet access on my public EC2 instance

Your public instance is live and reachable from the internet. In the next step, you will launch a second instance in the private subnet and discover what happens when there is no route to the internet gateway.

Launch an Instance in the Private Subnet and Hit the Wall

Your public instance is running, reachable from the internet, and confirmed to have full connectivity. The public subnet and internet gateway are doing their job.

But does the private subnet actually block internet access? Right now you are trusting that your route table configuration works. In this step, you will launch an instance in the private subnet and try to connect to it the same way you connected to the public one.

In this step, get ready to:
  • Launch an EC2 instance in the private subnet with no public IP.
  • Attempt to connect to the instance and discover what happens.
Launch the private instance

This instance will live in the private subnet, where the route table has no path to the internet gateway. The launch settings are almost identical to the public instance, but the network configuration is where things diverge.

  • In the EC2 console, click Instances in the left sidebar to return to the instances list.
  • Click Launch instances.
  • For Name, enter private-instance.
  • For Application and OS Images (Amazon Machine Image), keep Amazon Linux 2023 AMI selected.
  • For Instance type, keep t2.micro selected.
  • For Key pair, choose Proceed without a key pair.

Why no key pair?

EC2 Instance Connect pushes a temporary SSH key for each session, so you do not need a persistent key pair. This simplifies the project and avoids key management pitfalls.

  • Under Network settings, click Edit.
  • For VPC, select my-vpc.
  • For Subnet, select the private subnet (my-vpc-subnet-private1).
  • For Auto-assign public IP, select Disable.

Why disable the public IP?

A private subnet is private because its route table has no path to the internet gateway. Disabling the public IP reinforces this isolation. Even if a public IP were assigned, the instance still could not reach the internet because the route table has no 0.0.0.0/0 route pointing to the internet gateway.

  • For Firewall (security groups), choose Create security group.
  • For Security group name, enter private-sg.
  • The wizard creates a default SSH rule. Change its Source type to Custom.
  • Enter 10.0.0.0/16 in the source field.
  • Click Launch instance.

Why is the SSH source the VPC CIDR?

For the public instance, you set the SSH source to My IP because connections come directly from the internet. The private instance has no public IP, so SSH connections can only come from within the VPC.

Setting the source to 10.0.0.0/16 (the VPC's CIDR block) allows any resource inside the VPC to SSH into this instance. This is what the EC2 Instance Connect Endpoint will use in the next step.

  • Wait for the instance to reach Running state.
  • In the instances list, look at the Public IPv4 address column for private-instance. It shows a dash, meaning no public IP was assigned.

Compare this with public-instance in the same list. The public instance has an IP address in that column. The private instance does not. This is your first visible proof that the two subnets are configured differently.

Instance stuck in Pending?

It can take a minute or two for the instance to move from Pending to Running. Click the refresh icon in the instances list to update the status.

Help me troubleshoot my private instance not starting.

Attempt to connect and discover the problem

You connected to the public instance by clicking Connect and using EC2 Instance Connect. What do you think will happen when you try the same thing with the private instance?

  • Select private-instance in the instances list.
  • Click Connect.
  • On the EC2 Instance Connect tab, click Connect.

The connection fails. The console cannot reach your instance because it has no public IP address and the private subnet has no route to the internet.

Why did this fail?

EC2 Instance Connect (without an endpoint) needs a network path from the internet to your instance. For the public instance, that path exists: internet gateway, public route table, public IP.

The private instance has none of these. Its route table only has the local route (10.0.0.0/16 to local), it has no public IP, and there is no route to the internet gateway. The instance is genuinely isolated.

This is exactly what should happen. You built a private instance that is properly isolated. But now you face a real problem: you have no way to get into this instance to verify it works.

Your private instance is locked down and unreachable. In the next step, you will solve this problem using an EC2 Instance Connect Endpoint, a free AWS tunnel that lets you SSH into private instances without a bastion host or public IP.

Create an EC2 Instance Connect Endpoint

Your private instance is running in the private subnet, but as you discovered in the last step, you cannot reach it. There is no public IP and no internet route, so the standard EC2 Instance Connect option does not work.

The traditional fix is a bastion host, a separate instance in the public subnet that you SSH through to reach private instances. AWS offers a modern alternative. EC2 Instance Connect Endpoint is a free, managed tunnel that lets you reach private instances without extra infrastructure or cost.

In this step, get ready to:
  • Create an EC2 Instance Connect Endpoint in your private subnet.
  • Verify your security group allows SSH traffic from within the VPC.
  • Connect to the private instance through the endpoint tunnel.
Create the EC2 Instance Connect Endpoint

An EC2 Instance Connect Endpoint creates a secure, identity-aware tunnel from the AWS console directly into your VPC. No public IP is needed on the target instance, and no bastion host is needed in the public subnet.

Why not use a bastion host?

A bastion host is a separate EC2 instance you launch and maintain in the public subnet just to SSH through. It adds cost, requires patching, and needs its own security group management.

EC2 Instance Connect Endpoint removes all of that overhead. It is free, pushes a temporary SSH key for each session, and authenticates traffic through your IAM identity before it enters the VPC. AWS recommends using it instead of a NAT gateway when SSH access is the only reason for outbound connectivity.

  • Open the VPC console by navigating to https://console.aws.amazon.com/vpc/.
  • In the left navigation pane, click Endpoints.
  • Click Create endpoint.
  • For Name tag, enter my-eice.
  • For Type, select EC2 Instance Connect Endpoint.
  • For VPC, select my-vpc.
  • For Security groups, select the default security group for your VPC.
  • For Subnet, select your private subnet (my-vpc-subnet-private1).

Why the default security group?

The endpoint needs outbound SSH access to reach instances in your VPC. The default security group allows all outbound traffic, which satisfies this requirement. No custom rules are needed.

  • Click Create endpoint.
  • Wait for the endpoint status to change from Pending to Available. This can take 2-5 minutes.

Endpoint stuck on Pending?

EC2 Instance Connect Endpoints typically take 2-5 minutes to provision. If the status stays on Pending for more than 10 minutes, verify you selected the correct VPC and subnet.

Why is my EC2 Instance Connect Endpoint stuck on Pending?

Verify the private instance security group

The EC2 Instance Connect Endpoint routes SSH traffic from within the VPC. For this to work, private-sg must allow inbound SSH from the VPC CIDR (10.0.0.0/16).

  • Return to the EC2 console.
  • In the left sidebar, click Security Groups.
  • Select the private-sg security group.
  • Click the Inbound rules tab.
  • Confirm there is a rule for SSH (port 22) with source 10.0.0.0/16. You added this rule when you launched the private instance.

Don't see the SSH rule?

If the rule is missing, add it manually.

  • Click Edit inbound rules.
  • Click Add rule.
  • For Type, select SSH.
  • For Source, select Custom.
  • Enter 10.0.0.0/16 in the source field.
  • Click Save rules.

Why isn't my SSH security group rule working?

Connect to the private instance through the endpoint

The endpoint is active and the security group allows SSH from within the VPC. Time to test the tunnel.

  • In the left sidebar, click Instances.
  • Select private-instance.
  • Click Connect.
  • On the EC2 Instance Connect tab, for Connection type, select Connect using a Private IP.
  • For EC2 Instance Connect Endpoint, select the endpoint you created (my-eice).

Before you click Connect, what do you expect to happen? In Step 3, this same connection attempt failed because the instance had no public IP.

  • Click Connect.

A terminal opens in your browser. You are now connected to the private instance through the EC2 Instance Connect Endpoint tunnel, without a bastion host or public IP.

What just happened?

The EC2 Instance Connect Endpoint created a secure tunnel from the AWS console to your private instance. Traffic was authenticated by your IAM identity and routed through the endpoint inside your VPC.

The private instance never needed a public IP or an internet route. The endpoint handled the entire connection path within the VPC.

Connection failed?

  • Make sure the endpoint status is Available, not Pending.
  • Confirm that private-sg has an inbound SSH rule with source 10.0.0.0/16.
  • Verify you selected the correct endpoint (my-eice) and the correct instance (private-instance).

Why can't I connect to my private instance through the EC2 Instance Connect Endpoint?

You now have a secure tunnel into your private subnet. In the next step, you will put both instances to the ultimate test and prove that your VPC architecture actually enforces the network boundaries you designed.

Prove Network Isolation Works

In the previous step, you tunneled into your private instance using an EC2 Instance Connect Endpoint. You now have access to both instances in your VPC. One sits in the public subnet with a route to the internet gateway. The other sits in the private subnet with no internet route at all.

The final test is proving that your network architecture actually enforces the boundaries you designed. You will run the exact same commands on both instances and see completely different results.

In this step, get ready to:
  • Test internet access from the private instance and confirm it times out.
  • Run the same test on the public instance and confirm it succeeds.
  • Test private connectivity between subnets to confirm instances can still talk to each other.
Test internet access from the private instance

You should still have your shell session on private-instance open from the previous step. This is your chance to prove that the private subnet genuinely blocks internet access.

Before you run the next command, take a moment to predict: will this instance be able to reach the internet? Think about what routes exist in the private route table.

  • Test whether the private instance can reach the internet by running this command:
curl -s --connect-timeout 5 -o /dev/null -w "%{http_code}" https://aws.amazon.com

The command hangs for 5 seconds and then returns 000. The connection timed out. The private subnet has no route to the internet gateway, so the request has nowhere to go.

  • Confirm that ICMP traffic is also blocked by running this command:
ping -c 3 -W 3 8.8.8.8

This also times out. No packets received.

What does this prove?

Both curl and ping failed because the private route table has only one route: 10.0.0.0/16 to local. There is no 0.0.0.0/0 route pointing to the internet gateway, so outbound traffic to the internet is dropped.

Seeing a response instead of a timeout?

If curl returns 200 instead of timing out, your private instance may be in the wrong subnet. Go to the EC2 console, select private-instance, and check the Subnet ID on the Networking tab. It should match my-vpc-subnet-private1.

Help me figure out why my private instance can reach the internet

Compare with the public instance

Now run the same commands on the public instance and compare the results. Keep your private-instance tab open so you can see both results.

  • Open a new browser tab and navigate to the EC2 console at https://console.aws.amazon.com/ec2/.
  • Click Instances in the left sidebar.
  • Select public-instance.
  • Click Connect.
  • On the EC2 Instance Connect tab, click Connect.

What do you expect to see when you run the same curl command here? This instance is in the public subnet with a route to the internet gateway.

  • Test internet access from the public instance by running this command:
curl -s --connect-timeout 5 -o /dev/null -w "%{http_code}" https://aws.amazon.com

This time the command returns 200 immediately. The public subnet's route table has a 0.0.0.0/0 route to the internet gateway, so outbound traffic flows freely.

  • Verify that ICMP traffic also works by running this command:
ping -c 3 8.8.8.8

Ping succeeds with responses from 8.8.8.8. Three packets sent, three packets received.

What do these results prove?

You ran the exact same commands on two instances in the same VPC. The private instance returned 000 (timed out) and the public instance returned 200 (success).

The only difference between these two instances is which subnet they sit in, and which route table that subnet is associated with. Route tables are what make a subnet "public" or "private."

Getting a timeout on the public instance too?

Check that public-instance is in my-vpc-subnet-public1 by selecting it in the EC2 console and checking the Networking tab. Also confirm the public route table has a 0.0.0.0/0 route pointing to the internet gateway in the VPC console under Route tables.

Help me figure out why my public instance cannot reach the internet

Test private connectivity between subnets

You have proven that the private instance cannot reach the public internet. But can instances within the same VPC still talk to each other? Both route tables share the local route (10.0.0.0/16 to local), which allows traffic between any two addresses inside the VPC.

To test this, you will ping the private instance from the public instance using its private IP address. First, you need to update the private-sg security group to allow ICMP traffic from within the VPC.

  • Open a new browser tab and navigate to the EC2 console at https://console.aws.amazon.com/ec2/.
  • Click Security Groups in the left sidebar under Network & Security.
  • Select the private-sg security group.
  • Click the Inbound rules tab, then click Edit inbound rules.
  • Click Add rule.
  • For Type, select All ICMP - IPv4.
  • For Source, select Custom and enter 10.0.0.0/16.
  • Click Save rules.

Why allow ICMP from the VPC CIDR?

ICMP is the protocol that ping uses. By setting the source to 10.0.0.0/16, you are allowing ping requests only from other instances inside your VPC. Traffic from the public internet is still blocked.

Now you need the private instance's private IP address so you can ping it from the public instance.

  • In the EC2 console, click Instances in the left sidebar.
  • Select private-instance.
  • On the Details tab, find the Private IPv4 address field and record the value: private instance's private IPv4 address

Before you run the next command, predict: will the public instance be able to ping the private instance? Remember, the private instance has no public IP and no internet access.

  • Switch to your public-instance shell tab and ping the private instance by running this command:
ping -c 3 [[PRIVATE_INSTANCE_IP="private instance's private IPv4 address"]]

The ping succeeds. Three packets sent, three packets received. Even though the private instance has no internet access, the public instance can reach it over the VPC's internal network using the local route.

Why does the cross-subnet ping work?

Both the public and private route tables contain the local route: 10.0.0.0/16 to local. This route is automatically added to every route table in the VPC and cannot be removed.

It means any instance in the VPC can communicate with any other instance using private IP addresses, regardless of which subnet they are in. Internet access is controlled by the route tables, but internal VPC communication always works.

Ping timing out?

Make sure you added the All ICMP - IPv4 inbound rule to private-sg with the source set to 10.0.0.0/16. Without this rule, the security group blocks ICMP traffic even from inside the VPC.

Also double check that you are pinging the private IPv4 address (starting with 10.0.), not a public IP.

Help me troubleshoot why my cross-subnet ping is failing

Secret mission

Add a NAT Gateway for Private Subnet Internet Access

Your private instance is completely cut off from the internet. But what if it needed to download security patches or call an external API? In this mission, you will create a NAT gateway to give private instances outbound-only internet access, and add a second private subnet in a different Availability Zone for production-grade high availability.

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. Your EC2 instances are t2.micro and free tier eligible, but the VPC resources have no ongoing cost.

Cost warning

Two t2.micro instances running 24/7 use about 1,440 hours per month. The free tier only covers 750 hours per month total across all t2.micro instances, so leaving both running will exceed the free tier.

If you completed the Secret Mission and forgot to delete the NAT gateway, it costs $0.045 per hour plus $0.045 per GB of data processed. An unassociated Elastic IP costs about $0.005 per hour. Delete both immediately if they are still active.

Resources you used:

  • EC2 instances: public-instance and private-instance (free tier eligible t2.micro).
  • EC2 Instance Connect Endpoint: my-eice (no hourly cost).
  • VPC: my-vpc with subnets, route tables, internet gateway, and security groups (no ongoing cost).
  • Secret Mission only: NAT gateway, Elastic IP, second private subnet, and any test instances (should already be deleted if you followed the cleanup steps).

Keep everything running

No action needed. Choose this if you are still actively building on your VPC or plan to continue experimenting soon.

  • Monitor your free tier usage in the AWS Billing console to make sure your EC2 hours stay within the 750-hour monthly limit.
  • If you completed the Secret Mission, confirm that the NAT gateway and Elastic IP have been deleted. Check VPC > NAT gateways and EC2 > Elastic IPs to verify.

Pause - I'll come back to this later

Stop your EC2 instances to free up free tier hours while keeping your VPC and network configuration intact.

  • Navigate to the EC2 console.
  • Select Instances in the left sidebar.
  • Select both public-instance and private-instance.
  • Choose Instance state, then Stop instance.
  • If you launched a test instance during the Secret Mission, stop that one too.
  • Your VPC, subnets, route tables, internet gateway, security groups, and EC2 Instance Connect Endpoint remain in place at no cost. Minimal EBS storage charges may apply for the stopped instances.

Delete - I don't want to use this again

Remove all project resources and start fresh. Follow these steps in order.

Terminate all EC2 instances:

  • Navigate to the EC2 console.
  • Select Instances in the left sidebar.
  • Select public-instance and private-instance.
  • Choose Instance state, then Terminate instance.
  • If you launched a test instance during the Secret Mission, terminate that one too.

Delete the EC2 Instance Connect Endpoint:

  • Navigate to the VPC console.
  • Select Endpoints in the left sidebar.
  • Select my-eice.
  • Choose Actions, then Delete VPC endpoints.

If you completed the Secret Mission, check for leftover resources:

  • In the VPC console, select NAT gateways. If a NAT gateway is still listed as Available, select it, choose Actions, then Delete NAT gateway.
  • In the EC2 console, select Elastic IPs under Network & Security. If an Elastic IP is still allocated, select it, choose Actions, then Release Elastic IP addresses.

Delete the VPC:

  • In the VPC console, select Your VPCs in the left sidebar.
  • Select my-vpc.
  • Choose Actions, then Delete VPC.
  • This automatically removes all associated subnets, route tables, the internet gateway, and security groups.

Nice Work!

Nice Work!

Nice work! You just built a production-style VPC on AWS from scratch and proved that your network architecture enforces real security boundaries.

You've learned how to:

  • Build a custom VPC with public and private subnets controlled by separate route tables, proving that route tables are what make a subnet "public" or "private".
  • Launch EC2 instances in both subnets and prove network isolation by running the same curl command on each. The public instance returns 200 while the private one times out.
  • Use an EC2 Instance Connect Endpoint to securely tunnel into a private instance without a bastion host, public IP, or key pair.
  • Secret Mission: Completed an optional challenge to extend your VPC architecture with outbound internet access for private subnets.

Ready to quiz yourself?