Build a Custom VPC on AWS
Build a custom VPC with public and private subnets on AWS.
Introduction
30 Second Summary
Every time you visit a website, your request travels through a network that carefully controls what's public-facing and what's hidden behind the scenes. Banks, hospitals, and streaming services all use this same pattern to keep their databases safe while serving content to the world.
In this project, you will build a custom VPC (Virtual Private Cloud) on AWS from scratch. You will create separate public and private subnets to understand how real-world network architectures keep resources secure.
What You'll Build
A production-style VPC architecture on AWS with a public subnet hosting a web server and a private subnet isolated from direct internet access.
By the end of this project, you'll have:
- A custom VPC with public and private subnets, each with its own route table.
- A running EC2 instance in the public subnet that you can connect to from your browser using EC2 Instance Connect.
- A clear mental model of how VPC components (route tables, internet gateways, security groups) fit together.
- Secret Mission: Add a NAT Gateway so instances in the private subnet can reach the internet for outbound traffic without being directly exposed.
Are there any prerequisites?
You need an AWS account created after July 15, 2025, with free tier credits active. All work in this project happens in your browser via the AWS Management Console.
Set Up Your Environment
Every AWS service you deploy lives inside a network you design. That network is called a VPC (Virtual Private Cloud).
Before building one from scratch, you need your console pointed at the right region and your free tier credits confirmed. In this step, you will sign in, select your region, and locate the VPC Dashboard.
In this step, get ready to:
- Sign in to the AWS Management Console and set your region to us-east-1.
- Locate the VPC Dashboard and note the default VPC.
- Confirm your free tier credits are active.
Log in and set your region to us-east-1
AWS has data centres all over the world, grouped into regions. You need to pick one region and stick with it for the entire project so all your resources can communicate with each other.
- Open your browser and go to the AWS Management Console sign-in page at https://console.aws.amazon.com.
- Sign in with your AWS account credentials.
- In the top-right corner of the console, click the region selector dropdown.
- Select US East (N. Virginia) from the list.
The region selector should now display us-east-1 in the top-right corner.
Why us-east-1?
US East (N. Virginia) has the broadest service availability of any AWS region. Most tutorials and documentation reference it as the default, which makes troubleshooting easier when you are starting out.
Can't find the region selector?
Look for a short region name (like Ohio or Oregon) in the very top-right of the navigation bar, next to your account name. Click it to open the dropdown list of all available regions.
Help me find the region selector in the AWS Console
Navigate to the VPC Dashboard
The VPC Dashboard is your control centre for all networking resources. Every VPC, subnet, route table, and gateway you create in this project will be visible here.
- Click the search bar at the top of the console.
- Type VPC and select VPC from the search results.
You are now on the VPC Dashboard. Notice that AWS has already created a default VPC for your account.
- In the left navigation pane, click Your VPCs to see the default VPC listed.
Why not use the default VPC?
The default VPC comes pre-configured with subnets, an internet gateway, and route tables. That convenience hides how the pieces connect.
Building each component yourself forces you to understand the relationships between them. This is exactly what AWS Solutions Architect exam questions test when they ask "what is missing" in a broken network configuration.
Verify your free tier credits
Your AWS account includes $100 in sign-up credits that cover the resources in this project. A quick check now saves surprises later.
- Click the search bar at the top of the console.
- Type Billing and select Billing and Cost Management.
- Confirm that your credits are shown as available on the page.
- Navigate back to the VPC Dashboard by clicking the search bar, typing VPC, and selecting VPC from the results.
Don't see any credits?
Credits are available for accounts created on or after July 15, 2025. If your account was created before that date, your free tier works differently and you may not see a credits section. The VPC, subnets, and route tables in this project are free regardless of account type.
Help me check my AWS free tier status and credits
Your environment is ready. Next up, you will create a custom VPC and build out its public and private subnets from scratch.
Create the Custom VPC and Subnets
Your environment is ready. Now it's time to build the actual network your cloud resources will live inside.
Every AWS resource you deploy needs a network to sit on. Instead of using the default VPC that AWS created for your account, you will build a custom one from scratch. This gives you full control over the IP address range, subnet layout, and traffic routing.
In this step, get ready to:
- Create a custom VPC with a large IP address range.
- Create a public subnet and a private subnet inside the VPC.
- Enable auto-assign public IPv4 on the public subnet only.
Create your custom VPC
A CIDR block defines the range of IP addresses available inside your VPC. You will use 10.0.0.0/16, which gives you 65,536 IP addresses to carve into subnets later.
- In the VPC Dashboard, choose Create VPC.
- For Resources to create, select VPC only.
- Set the Name tag to MyCustomVPC.
- For IPv4 CIDR block, enter 10.0.0.0/16.
- Leave IPv6 CIDR block set to No IPv6 CIDR block.
- Leave Tenancy set to Default.
- Choose Create VPC.
Why VPC only instead of VPC and more?
The "VPC and more" option automates creating subnets, route tables, and gateways all at once. By selecting "VPC only", you build each piece individually. This forces you to understand how the components connect, which is critical for troubleshooting and for exam questions that ask "what's missing" when connectivity fails.
What is a CIDR block?
CIDR (Classless Inter-Domain Routing) is a way of expressing a range of IP addresses. The number after the slash is the prefix length. A /16 gives you 65,536 addresses. A /24 gives you 256.
Think of it like a phone area code. The VPC's /16 is the area code (10.0), and each subnet's /24 is a neighbourhood within that area.
You should see a green success banner confirming your VPC was created.
Don't see the Create VPC button?
Make sure you are on the VPC Dashboard, not inside an existing VPC's detail page. In the left navigation pane, choose Your VPCs and look for the Create VPC button at the top right.
Help me find the Create VPC button in the AWS console.
Create the public and private subnets
Subnets divide your VPC's IP range into smaller segments. You will create two: one for internet-facing resources and one for isolated internal resources.
- In the left navigation pane, choose Subnets.
- Choose Create subnet.
- Under VPC ID, select MyCustomVPC.
- Set Subnet name to Public-Subnet.
- For Availability Zone, select us-east-1a.
- For IPv4 subnet CIDR block, enter 10.0.0.0/24.
- Choose Add new subnet to add a second subnet in the same form.
- Set Subnet name to Private-Subnet.
- For Availability Zone, select us-east-1a.
- For IPv4 subnet CIDR block, enter 10.0.1.0/24.
- Choose Create subnet.
Why put both subnets in the same Availability Zone?
Each subnet must reside entirely within one Availability Zone. For this project, placing both subnets in us-east-1a keeps things simple. In production, you would spread subnets across multiple Availability Zones for high availability.
You should see a success message confirming both subnets were created.
Seeing a CIDR overlap error?
This means the CIDR blocks you entered overlap with each other or with an existing subnet. Double-check that the public subnet uses 10.0.0.0/24 and the private subnet uses 10.0.1.0/24. The third octet (0 vs 1) is what makes them different, non-overlapping ranges.
Help me fix a CIDR overlap error when creating subnets.
Enable auto-assign public IPv4 on the public subnet
By default, instances launched in your subnets do not get a public IP address. You need to enable this setting on the public subnet so that any EC2 instance launched there is automatically reachable from the internet.
- In the Subnets list, select the checkbox next to Public-Subnet.
- Choose Actions, then Edit subnet settings.
- Check the box for Enable auto-assign public IPv4 address.
- Choose Save.
Why only the public subnet?
A public subnet is one whose instances can be reached from the internet. Giving instances a public IP is one part of that. The private subnet stays isolated because its instances have no public IP and no route to the internet.
Do NOT enable auto-assign public IPv4 on Private-Subnet. That would defeat its purpose as an isolated network segment.
You should see a success banner confirming the subnet settings were updated.
Don't see the Actions dropdown?
Make sure you have selected the checkbox next to Public-Subnet in the subnets list. The Actions dropdown only becomes active when a subnet is selected.
Help me find the Edit subnet settings option.
Your custom VPC now has two distinct network segments. Next up, you will wire the public subnet to the internet by creating an Internet Gateway and a custom route table.
Configure the Internet Gateway and Route Tables
Your VPC and subnets are in place, but right now nothing inside them can reach the internet.
In this step, you will build the networking plumbing that connects your public subnet to the outside world. You will create an Internet Gateway, attach it to your VPC, and then create a route table that directs outbound traffic through that gateway.
In this step, get ready to:
- Create and attach an Internet Gateway to MyCustomVPC.
- Create a custom route table with a route to the Internet Gateway.
- Associate the public subnet with the new route table to enable internet access.
Create and attach the Internet Gateway
An Internet Gateway is the door between your VPC and the public internet. Without one attached, no resource inside the VPC can send or receive traffic from outside.
- In the left navigation pane of the VPC Dashboard, choose Internet gateways.
- Choose Create internet gateway.
- For Name tag, enter MyIGW.
- Choose Create internet gateway.
The gateway is created, but it is not connected to any VPC yet. You will see a green banner at the top of the page with an option to attach it.
- Choose Attach to a VPC from the green banner at the top of the page.
- In the Available VPCs dropdown, select MyCustomVPC.
- Choose Attach internet gateway.
The State column for MyIGW should now show Attached.
What is an Internet Gateway?
An Internet Gateway is a horizontally scaled, redundant VPC component that allows communication between instances in your VPC and the internet. It performs network address translation (NAT) for instances that have a public IPv4 address.
Think of it as the gateway between your private network and the rest of the world. A subnet that has a route to an Internet Gateway is called a public subnet.
Don't see Attach to a VPC?
If the green banner disappeared, select MyIGW from the Internet gateways list, then choose Actions and Attach to VPC.
If MyCustomVPC does not appear in the dropdown, make sure you are in the us-east-1 region (check the top-right corner of the console).
Need more help? Help me attach my Internet Gateway to MyCustomVPC.
Create the custom route table and add the internet route
A route table contains rules that determine where network traffic is directed. You will create a custom route table that tells traffic destined for the internet (0.0.0.0/0) to go through your Internet Gateway.
- In the left navigation pane, choose Route tables.
- Choose Create route table.
- For Name, enter Public-RT.
- For VPC, select MyCustomVPC.
- Choose Create route table.
The route table detail page opens. By default it only has the local route (10.0.0.0/16), which allows traffic within the VPC.
- Choose the Routes tab.
- Choose Edit routes.
- Choose Add route.
- For Destination, enter 0.0.0.0/0.
- For Target, select Internet Gateway, then select MyIGW.
- Choose Save changes.
What does 0.0.0.0/0 mean?
The destination 0.0.0.0/0 is a catch-all route that matches any IP address not covered by a more specific route. It tells the VPC: "for any traffic heading somewhere outside the VPC, send it to the Internet Gateway."
Traffic going to 10.0.0.0/16 (addresses within the VPC) still matches the local route, which is more specific. The internet route only catches everything else.
Don't see MyIGW in the Target dropdown?
Make sure you selected Internet Gateway as the target type first. Only after selecting the type will the specific gateways appear in the list.
If no gateways appear at all, confirm that MyIGW was attached to MyCustomVPC in the previous substep.
Need more help? Help me add a route to my Internet Gateway in the Public-RT route table.
Associate the public subnet with the route table
The route table exists, but no subnet is using it yet. You need to explicitly link your Public-Subnet to Public-RT so that traffic from that subnet follows the internet route.
- While still on the Public-RT route table detail page, choose the Subnet associations tab.
- Choose Edit subnet associations.
- Check the box next to Public-Subnet.
- Choose Save associations.
Why does the private subnet stay isolated?
When you created MyCustomVPC, AWS automatically created a main route table for it. Any subnet not explicitly associated with a custom route table is implicitly associated with this main route table.
The main route table only has the local route (10.0.0.0/16), meaning Private-Subnet can communicate within the VPC but has no path to the internet. This is the standard AWS security pattern: keep the main route table restrictive and create custom route tables only for subnets that need internet access.
Verify your configuration by checking that the Routes tab on Public-RT shows two routes:
- 10.0.0.0/16 with target local.
- 0.0.0.0/0 with target MyIGW.
- Confirm the Subnet associations tab shows Public-Subnet listed under Explicit subnet associations.
- Navigate to the main route table for MyCustomVPC (the one NOT named Public-RT, marked Yes in the Main column).
- Confirm its Routes tab shows only the local route (10.0.0.0/16) and that Private-Subnet is listed under Subnets without explicit associations.
Public-Subnet not appearing in the association list?
Make sure you selected the route table named Public-RT (not the main route table) before choosing Edit subnet associations.
Only subnets that belong to the same VPC as the route table will appear. If you do not see either subnet, confirm that Public-RT was created for MyCustomVPC (check the VPC column on the Route tables page).
Need more help? Help me associate Public-Subnet with my Public-RT route table.
Your networking plumbing is complete. Public-Subnet now has a clear path to the internet through MyIGW, while Private-Subnet remains completely isolated. Next up, you will launch an EC2 instance in the public subnet and prove the connectivity works.
Launch an EC2 Instance in the Public Subnet
Your network is built. You have a VPC with two subnets, an Internet Gateway, and route tables that control which subnet can reach the internet.
But a network without anything running inside it is just empty infrastructure. In this step, you will launch an EC2 instance (a virtual server) inside the public subnet. This is the moment your architecture becomes real.
In this step, get ready to:
- Launch a t3.micro EC2 instance in your public subnet.
- Create a security group that allows SSH and HTTP access.
- Verify the instance is running with a public IP address.
Configure the instance name and type
Every EC2 instance needs a name, an operating system (AMI), and a size (instance type). You will pick the smallest free-tier-eligible option so this costs nothing from your credits.
- Search for EC2 in the top search bar and select the EC2 service.
- Choose Launch instance.
- Under Name and tags, set the Name to Public-Web-Server.
- Under Application and OS Images, select Amazon Linux 2023 AMI.
- Confirm it is marked Free tier eligible.
- Under Instance type, select t3.micro.
Why t3.micro?
For AWS accounts created after July 15, 2025, t3.micro is the smallest free-tier-eligible instance type. It is covered by your $100 sign-up credit for up to 6 months.
Set up networking and security
This is where you connect the instance to your custom VPC and create a Security Group. A security group acts as a virtual firewall that controls which traffic can reach your instance.
- Under Key pair (login), select Proceed without a key pair.
- Under Network settings, choose Edit.
- Set VPC to MyCustomVPC.
- Set Subnet to Public-Subnet.
- Set Auto-assign public IP to Enable.
- Under Firewall (security groups), choose Create security group.
- Set Security group name to Public-SG.
- For the first inbound rule, set Type to SSH and Source type to Anywhere (0.0.0.0/0).
- Choose Add security group rule.
- For the second rule, set Type to HTTP and Source type to Anywhere (0.0.0.0/0).
Why no key pair?
You will connect to this instance using EC2 Instance Connect, a browser-based terminal built into the AWS Console. It is pre-installed on Amazon Linux 2023 and does not require a key pair.
This eliminates the need to manage SSH keys or configure PuTTY. You just click Connect in the console.
Why allow SSH from anywhere?
EC2 Instance Connect needs port 22 open. Setting the source to 0.0.0.0/0 allows connections from any IP, which is acceptable for a learning environment. In production, you would restrict this to specific IP ranges.
Launch the instance and verify it is running
- Leave all other settings as default.
- Choose Launch instance.
- Choose View all instances to go to the Instances list.
- Wait for the Instance state column to show Running and the Status check column to show 2/2 checks passed.
Status checks take 1-2 minutes
You can click the refresh icon in the instances list to update the status. The instance needs to pass both the system check and the instance check before you can connect.
Once your instance shows Running, select it and look at the Details tab at the bottom. You should see a Public IPv4 address assigned. This confirms your public subnet's auto-assign setting is working.
No public IP address showing?
If your instance has no public IPv4 address, you likely selected the wrong subnet or did not set Auto-assign public IP to Enable during launch. Terminate this instance and launch a new one with the correct settings.
Also confirm you selected Public-Subnet (not Private-Subnet) under Network settings.
Help me troubleshoot why my EC2 instance has no public IP address.
Your EC2 instance is live inside your custom VPC. Next up, you will connect to it from the browser and prove that your entire network architecture is working end to end.
Connect and Verify Your Network Architecture
Your EC2 instance is running in the public subnet with all the networking components in place. Now it is time to prove that the architecture actually works.
In this step, you will connect to your instance directly from the browser and run commands that verify internet connectivity. You will also confirm that the private subnet remains completely isolated from the internet.
In this step, get ready to:
- Connect to your EC2 instance using EC2 Instance Connect (a browser-based terminal).
- Test outbound internet access from the public subnet.
- Verify that the private subnet has no internet route.
Connect to your instance via EC2 Instance Connect
EC2 Instance Connect gives you a browser-based terminal session. Because your instance uses Amazon Linux 2023, the Instance Connect agent is pre-installed. No key pair or SSH client is needed.
- In the EC2 console, select Public-Web-Server from the instances list.
- Click Connect at the top of the page.
- On the Connect to instance page, select the EC2 Instance Connect tab.
- Leave the username as ec2-user.
- Click Connect.
A browser-based terminal opens. You should see a command prompt showing ec2-user and the instance's private IP address.
What is EC2 Instance Connect?
EC2 Instance Connect is a browser-based SSH connection that pushes a temporary key to your instance's metadata. The key is only valid for 60 seconds during the handshake. After that, you have a regular SSH session without ever managing key files.
Connection timed out or failed?
Make sure your instance shows Running in the Instance state column and 2/2 checks passed in the Status check column. If the status checks have not passed yet, wait another minute and try again.
If the instance is running but connection still fails, verify that your security group Public-SG has an inbound rule allowing SSH (port 22) from 0.0.0.0/0. Also confirm the instance is in Public-Subnet (which has a route to the Internet Gateway).
Still stuck? Why can't I connect to my EC2 instance using EC2 Instance Connect?
Test internet connectivity from the public subnet
With the terminal open, you can now prove that your instance has outbound internet access. This confirms the full chain: instance in public subnet, route table sends 0.0.0.0/0 to the Internet Gateway, and the Internet Gateway provides NAT between the instance's private IP and its public IP.
- Check your instance's public IP address by running this command:
curl -s http://checkip.amazonaws.com
What does this command do?
This curl command sends a request to an AWS-hosted service that replies with the public IP address it sees. If you get an IP address back, your instance can reach the internet successfully.
The returned IP should match the Public IPv4 address shown in your EC2 console for Public-Web-Server.
- Confirm DNS resolution and ICMP connectivity by running:
ping -c 3 google.com
You should see three replies with round-trip times, confirming that DNS resolved google.com to an IP address and ICMP packets traveled to the internet and back.
Why two tests?
The curl command tests HTTP (TCP port 80) connectivity. The ping command tests ICMP and DNS resolution. Together they prove that multiple protocols work through your Internet Gateway.
Not getting a response?
If curl hangs or returns nothing, check that Public-RT has a route with destination 0.0.0.0/0 targeting MyIGW. Also verify that Public-Subnet is explicitly associated with Public-RT (not the main route table).
If ping fails but curl works, that is normal for some environments. Google may block ICMP in certain regions. The curl result alone is sufficient proof of internet connectivity.
Need more help? Help me debug why my EC2 instance in a public subnet cannot reach the internet.
Verify that the private subnet has no internet route
Your public subnet works. Now confirm the flip side: the private subnet is isolated. Any instance launched there would have no path to the internet because its route table lacks an Internet Gateway route.
- Navigate back to the VPC console by searching VPC in the top search bar and selecting the VPC service.
- In the left navigation pane, choose Route tables.
- Select the main route table for MyCustomVPC (the one that is NOT named Public-RT).
- Click the Routes tab and examine the entries.
You should see only one route: destination 10.0.0.0/16 with target local. There is no 0.0.0.0/0 entry. This means traffic from the private subnet can only reach other resources inside the VPC.
- Click the Subnet associations tab.
- Confirm that Private-Subnet appears under Subnets without explicit associations. This means it is implicitly associated with this main route table.
Why is the private subnet isolated?
When you create a VPC, AWS automatically creates a main route table with only the local route. Any subnet not explicitly associated with a custom route table uses this main route table by default.
Because you associated only Public-Subnet with Public-RT (which has the Internet Gateway route), Private-Subnet remains on the restrictive main route table. This is the standard AWS security pattern: keep the main route table locked down and create custom route tables only for subnets that need internet access.
Seeing an internet route on the main route table?
If you see a 0.0.0.0/0 route targeting MyIGW on the main route table, you accidentally added the route to the wrong table in Step 3. Select that route, choose Edit routes, and remove the 0.0.0.0/0 entry. Then confirm that Public-RT still has that route instead.
Need help sorting out your route tables? Help me fix my route table configuration so the private subnet is isolated.
You have now verified the entire network architecture end-to-end. Your public subnet has a working internet path, and your private subnet is completely isolated. This is the foundation of secure AWS network design.
Secret mission
Add a NAT Gateway for Private Subnet Internet Access
Your private subnet is completely isolated from the internet. But what if instances there need to download updates or call external APIs? In this secret mission, you will add a NAT Gateway that gives private instances outbound internet access without exposing them to inbound traffic.
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 VPC, subnets, route tables, and Internet Gateway are free. The EC2 instance consumes credits at approximately $0.01/hour total (instance + public IPv4 address).
Cost warning
Your Public-Web-Server instance is consuming free tier credits while running. At approximately $0.01/hour, this is negligible for a few days but adds up over weeks. If you are not actively using it, stop or terminate the instance.
Resources you used:
- VPC: MyCustomVPC (10.0.0.0/16). Free.
- Subnets: Public-Subnet (10.0.0.0/24) and Private-Subnet (10.0.1.0/24). Free.
- Route tables: Public-RT and the main route table. Free.
- Internet Gateway: MyIGW. Free.
- Security Group: Public-SG. Free.
- EC2 instance: Public-Web-Server (t3.micro). Covered by free tier credits while running.
- Public IPv4 address: $0.005/hour while the instance is running (covered by credits).
Keep everything running
No action needed. Choose this if you are still actively experimenting with your VPC or plan to launch more instances in it soon.
- Your EC2 instance and VPC will continue consuming credits at approximately $0.01/hour total.
- This is negligible for a few days but adds up over weeks.
- Consider stopping the instance when you are not using it to preserve credits.
Pause - I'll come back to this later
Stop the EC2 instance to free up credits while keeping all your networking components intact. You can start the instance again later.
- Navigate to the EC2 console by searching for "EC2" in the top search bar.
- In the left navigation pane, choose Instances.
- Select Public-Web-Server.
- Choose Instance state, then Stop instance.
- Choose Stop when prompted for confirmation.
What happens when you stop an instance?
The public IPv4 address is released when you stop the instance. A new public IP is assigned when you start it again.
The VPC, subnets, route tables, Internet Gateway, and security group remain at no cost. You can start the instance again anytime from the same menu.
Delete - I don't want to use this again
Remove all project resources permanently. This cannot be undone.
First, terminate the EC2 instance:
- Navigate to the EC2 console by searching for "EC2" in the top search bar.
- In the left navigation pane, choose Instances.
- Select Public-Web-Server.
- Choose Instance state, then Terminate (delete) instance.
- Choose Terminate (delete) when prompted for confirmation.
- Wait for the instance state to show terminated (this takes about a minute).
Next, delete the VPC and all associated networking components:
- Navigate to the VPC console by searching for "VPC" in the top search bar.
- In the left navigation pane, choose Your VPCs.
- Select MyCustomVPC.
- Choose Actions, then Delete VPC.
- AWS displays a list of resources it will delete alongside the VPC (subnets, route tables, security groups, and the Internet Gateway). Review this list to confirm it matches your project resources.
- Type delete in the confirmation field and choose Delete.
What does Delete VPC remove?
When you delete a VPC using the AWS console, it automatically removes the associated subnets, route tables, security groups, network ACLs, and Internet Gateway for you. You only need to terminate EC2 instances manually first.
If you completed the Secret Mission, those resources (NAT Gateway, Elastic IP, IAM role, and private instance) were already deleted during the mission teardown steps.
Nice Work!
Nice Work!
You just built a production-style VPC from scratch on AWS. This is the foundational networking architecture that every real-world AWS deployment sits on top of.
You've learned how to:
- Built a custom VPC with separate public and private subnets, each with its own CIDR block and routing behaviour.
- Configured an Internet Gateway and custom route table to give the public subnet internet access while keeping the private subnet isolated.
- Launched a free-tier EC2 instance and connected via EC2 Instance Connect, verifying the full networking chain from instance to internet.
- Secret Mission: Added a NAT Gateway to enable outbound-only internet access from the private subnet, using Systems Manager Session Manager to connect to a private instance.
Ready to quiz yourself?