Day 8: Test your network (prove it works)

How to validate your VPC infrastructure by launching a test instance and verifying connectivity
Trust, but verifyโ
Days 3-7: You built the entire network infrastructure
Today: We prove it actually works
Here's the situation:
You've built:
โ
VPC with Internet Gateway
โ
Public and private subnets
โ
NAT Gateway
โ
Route Tables
โ
Security Groups
But you haven't actually tested any of it.
What if:
- NAT Gateway isn't running correctly?
- Route tables have the wrong associations?
- Secure Groups are blocking traffic?
- Something is misconfigured?
You'd fund out after deploying your containers (painful debugging)
Solution: Test first, deploy second.
Think of it like this:
You just built a house
Before moving in your furniture, you:
- Test the lights (do they work?)
- Test the water (does it flow?)
- Test the doors (do they lock?)
Same with infrastructure:
- Test the internet (can instances connect?)
- Test the NAT (does private โ internet work?)
- Test the routing (does traffic flow correctly?)
By the end of today, you'll have:
โ
Test EC2 instance running in private subnet
โ
Verified internet connectivity through NAT
โ
Confirmed routing works correctly
โ
Proof your infrastructure is ready
Let's test your network.
What you'll build todayโ
A temporary test setup:
| Component | Purpose | Duration |
|---|---|---|
| EC2 Instance | Test internet connectivity | Temporary (delete after testing) |
| Test-SG | Security Group for SSH access | Temporary (delete after testing) |
| SSH Connection | Access instance to run tests | Just for this tutorial |
It is important to delete all the instances we'll spin up today, to avoid ongoing cost.
We'll test:
- Can the instance reach the internet via NAT?
- Are route tables configured correctly?
- Do Security Groups work as expected?
Then we'll delete everything (no ongoing costs).
What you'll learnโ
- How to launch an EC2 instance in a private subnet
- How to connect to an instance using Session Manager (no SSH keys needed!)
- How to verify NAT Gateway is working
- How to test routing and connectivity
- How to clean up test resources
But if you want:
โ
Complete codebase (one clean repo)
โ
Complete walkthroughs
โ
Support when stuck
โ
Production templates
โ
Advanced features
Join the waitlist for the full course (launching February 2026):
Building something with AI calling?
Let's chat about your use case!
Schedule a free call โ - no pitch, just two builders talking.
Time requiredโ
30 minutes (launch instance + run tests + cleanup)
Prerequisitesโ
โ
Completed Day 3 (VPC) โ
โ
Completed Day 4 (Subnets) โ
โ
Completed Day 5 (NAT Gateway) โ
โ
Completed Day 6 (Route Tables) โ
โ
Completed Day 7 (Security Groups) โ
โ
Access to AWS Console
Understanding the test approachโ
Why test in a private subnet?โ
Your AI container will run in private subnets.
So we need to verify:
- Can private subnets reach the internet via NAT?
- Are route tables pointing to the right targets?
- Does the NAT Gateway actually work?
Testing in a private subnet simulates your production setup.
How we'll connect (Session Manager)โ
Traditional way: SSH with key pairs
- Need to generate SSH keys
- Need to manage
.pemfiles - Need a bastion host in public subnet
Modern way: AWS Systems Manager Session Manager
- No SSH keys needed
- Connect directly from browser
- Works with private subnets
We'll use Session Manager (easier).
What we'll testโ
Test 1: Internet connectivity
ping -c 8.8.8.8
Expected: Packets reach Google DNS (via NAT Gateway)
Test 2: DNS resolution
nslookup google.com
Expected: Resolves to an IP address
Test 3: HTTP request
curl -I https://www.google.com
Expected: Returns HTTP 200 response
If all three pass โ your network works โ
Step 1: Create Security Groups for test instanceโ
We need a Security Group that allows Session Manager access.
Open the AWS Console โIn the search bar, type VPC and click VPC from the dropdown:

In the search bar at the top, type VPC and click VPC from the dropdown

Click Security Groups in the left menu
You should see the two Security Groups we created in yesterday's post (and a default one created by AWS):

You should see the two Security Groups we created in yesterday's post (and a default one created by AWS)

Click Create security group
Fill in the basic details:
Click the icon
and copy each value from the table below โฌ| Field | Value |
|---|---|
| Security group name | |
| Description | |
| VPC | Select your VPC |
Select your VPC from the dropdown:

Select your VPC from the dropdown
Scroll down to Inbound rules.
Inbound rules:
- Leave empty (Session Manager doesn't need inbound rules)

Leave inbound rule empty (Session Manager doesn't need inbound rules)
Scroll down to Outbound rules.
Outbound rules:
- Keep default (All traffic to
0.0.0.0/0)

Keep default outbound rule (All traffic to 0.0.0.0/0)

Click Create Security Group
You should see: "Security group created successfully" โ

You should see: "Security group created successfully"
Step 2: Launch test EC2 instanceโ
Now let's launch a small instance in PrivateSubnet-1.
In the search bar at the top, type ec2 and click EC2 from the dropdown menu:

In the search bar at the top, type ec2 and click EC2 from the dropdown menu

Click launch instance
Configure the instance:
-
Name your instance
Name: -
Scroll down to Amazon Machine Image (AMI)
Select: Amazon Linux 2023

Scroll down to Amazon Machine Image (AMI), select Amazon Linux 2023
- Scroll down to Instance type
Select: t2.micro (free tier eligible)

Scroll down to Instance type, select:** t2.micro (free tier eligible)
- Scroll down to Key pair
Select: Proceed without a key pair (we're using Session Manager)

Scroll down to Key pair,select Proceed without a key pair (we're using Session Manager)
- Scroll to Network settings

Click Edit next to Network settings
Configure:
| Field | Value |
|---|---|
| VPC | Select your VPC |
| Subnet | Select PrivateSubnet-1 |
| Auto-assign public IP | Disable (private subnet doesn't need public IP) |
| Firewall (security groups) | Select existing โ Test-Instance-SG |

Configure the network settings
- Scroll down to Advanced details and expand it:

Scroll down to Advanced details and expand it
We need to create an IAM role for Session Manager.
Click Create new IAM profile:
Click Create new IAM profile
This opens a new tab.
In the new tab:
- Click Create role

In the new tab, click Create role
- Trusted entity type: select AWS service
- Use case: select EC2

Select AWS service and EC2
- Click Next

Click Next
- Search for and select :

Search for and select AmazonSSMManagedInstanceCore
- Click Next:

Click Next
- Name the role:

Name the role EC2-SSM-Role
- Scroll all the way down and click Create role:

Scroll all the way down and click Create role
You should see "Role created" โ

You should see "Role created" โ
Close the IAM tab and go back to the EC2 launch tab and refresh the IAM instance profile dropdown:

Close the tab and go back to the EC2 launch tab and refresh the IAM instance profile dropdown

Select the EC2-SSM-Role we just created

Click Launch instance
โ You should see: "Successfully initiated launch of instance"

You should see: "Successfully initiated launch of instance"

Click Instances to go back to the main menu and wait 2-3 minutes for the instance to initialize
Step 3: Connect using Session Managerโ
Once the instance shows Running and passes status checks:

Once the instance shows Running and passes status checks

Select your instance and click Connect

Click the Session Manager tab

Click Connect
This opens a terminal in your browser:

This opens a terminal in your browser
You're now connected to your instance.
Step 4: Test internet connectivityโ
Now let's verify the instance can reach the internet via NAT Gateway.
Test 1: Ping Google DNSโ
In the Session Manager terminal, run:
ping -c 4 8.8.8.8
You'll see an output:

You'll see an output
Expected output:
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=1.85 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=1.25 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=116 time=1.22 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=116 time=1.26 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 1.221/1.395/1.854/0.264 ms
โ
If you see responses โ NAT Gateway is working!
โ If you see timeouts โ something is wrong (skip to troubleshooting)
Test 2: DNS resolutionโ
Press Ctrl + L and that should clear the terminal outputs
nslookup google.com
Expected output:
Server: 172.31.0.2
Address: 172.31.0.2#53
Non-authoritative answer:
Name: google.com
Address: 192.178.155.113
....

Expected output from DNS resolution test
โ If you see IP addresses โ DNS is working!
Test 3: HTTP requestโ
Run this in the Session Manager terminal:curl -I https://www.google.com
Expected output:
HTTP/2 200
content-type: text/html; charset=ISO-8859-1
...

Expected output from HTTP request test
โ
If you see HTTP/2 200 โ Full internet access works!
Step 5: Verify routingโ
Let's check the route table to confirm traffic is going through NAT.
Press Ctrl + L and that should clear the terminal outputs
ip route
Expected output:
default via 172.31.128.1 dev enX0 proto dhcp src 172.31.138.2 metric 512
172.31.0.2 via 172.31.128.1 dev enX0 proto dhcp src 172.31.138.2 metric 512
172.31.128.0/20 dev enX0 proto kernel scope link src 172.31.138.2 metric 512
172.31.128.1 dev enX0 proto dhcp scope link src 172.31.138.2 metric 512

Expected output from verifying NAT Gateway routing
What this means:
default via 172.31.128.1= Default route points to the subnet gateway- The subnet gateway routes to NAT Gateway (via PrivateRouteTable)
This confirms routing is configured correctly โ
Step 6: Test outbound traffic from private subnetโ
Let's verify your instance can reach external APIs (simulating OpenAI/Twilio).
Run this in the Session Manager terminal:curl -s https://api.ipify.org
This returns your instance's public IP (the NAT Gateway's elastic IP).
Expected output:
52.55.183.190

Expected output from verifying outbound connectivity
This is your NAT Gateway's public IP.
What it proves:
โ
Private instance can reach the internet
โ
Requests go through NAT Gateway
โ
NAT translates private IP โ public IP
โ
External services see NAT's IP (not instance's private IP)
This is exactly how your Fargate containers will reach OpenAI/Twilio in coming steps.
Remember to clean up test resources, we'll do that in the next step.
We'll delete these test resources to avoid charges.
Step 7: Clean up test resourcesโ
Delete these test resources now to avoid charges.
Terminate the Session Managerโ
Click Terminate:
Click Terminate

Click Terminate to confirm
Terminate the instanceโ
In the search bar at the top, type ec2 and click EC2 from the dropdown menu:

In the search bar at the top, type ec2 and click EC2 from the dropdown menu

Click Instances in the left menu

Select Network-Test-Instance, then click Instance state and then click Terminate (delete) instance

Click Terminate to confirm deleting the test instance
Delete the Security Groupโ
In the search bar, type VPC and click VPC from the dropdown:

In the search bar at the top, type VPC and click VPC from the dropdown

Click Security Groups in the left menu

Select Test-Instance-SG then click Actions and click Delete security groups in the dropdown
Delete the IAM roleโ
In the search bar, type iam and click IAM from the dropdown:

In the search bar at the top, type IAM and click IAM from the dropdown

Click Roles in the left menu

Search for EC2-SSM-Role, select it and click Delete

Write the role name EC2-SSM-Role and click Delete to confirm
That's it! All test resources cleaned up.
Only delete:
โ
Network-Test-Instance
โ
Test-Instance-SG
โ
EC2-SSM-Role
Keep everything else:
โ Don't delete VPC
โ Don't delete NAT Gateway
โ Don't delete Route Tables
โ Don't delete ALB-SG or Fargate-SG
Today's winโ
If all tests passed:
โ Launched test instance in private subnetโ Connected using Session Manager
โ Verified internet connectivity via NAT Gateway
โ Confirmed DNS resolution works
โ Tested HTTP requests succeed
โ Verified routing configuration
โ Cleaned up test resources
You just proved your infrastructure works.
Your network is production-ready.
Tomorrow, we start building the load balancer.
Understanding what you provedโ
Today's tests confirmed:
1. NAT Gateway worksโ
- Private subnet โ NAT โ Internet โ
- Ping succeeded
- HTTP requests worked
2. Route Tables are correctโ
PrivateRouteTablepoints to NAT โ- Default route configured correctly
3. Security Groups allow necessary trafficโ
- Outbound traffic from private subnet works โ
- Instance could reach external APIs
4. DNS resolution worksโ
- Instance can resolve domain names โ
- Critical for calling apis.openai.com, api.twilio.com
Why this matters for your AI containersโ
Everything you tested today applies for Fargate:
| What we tested | How Fargate will use it |
|---|---|
| Internet via NAT | Pull Docker images from ECR |
| DNS resolution | Resolve apis.openai.com |
| HTTP requests | Call OpenAI Realtime API |
| Outbound traffic | Send audio to Twilio |
If the test instance could do it, Fargate can too.
You've de-risked the deployment.
Here's what we tested and proved visually:

This is how we prove that NAT Gateway is working
Troubleshootingโ
Ping times out (no response from 8.8.8.8)
Possible causes:
1. NAT Gateway not configured correctly
- Go to VPC โ NAT Gateways
- Status should be "Available"
- Check it's in a public subnet
2. PrivateRouteTable missing NAT route
- Go to VPC โ Route Tables โ PrivateRouteTable
- Should have route:
0.0.0.0/0 โ nat-xxxxx
3. Instance in wrong subnet
- Check instance is in PrivateSubnet-1 or PrivateSubnet-2
- Not in PublicSubnet-1 or PublicSubnet-2
4. PublicRouteTable missing IGW route
- NAT needs internet access
- PublicRouteTable should have:
0.0.0.0/0 โ igw-xxxxx
5. NAT Gateway in wrong availability zone
- If instance is in PrivateSubnet-1 (us-east-1a)
- NAT should be accessible from that AZ
Can't connect with Session Manager
Possible causes:
1. No IAM role attached
- Instance needs EC2-SSM-Role
- Check EC2 โ Actions โ Security โ Modify IAM role
2. Session Manager not installed (rare)
- Amazon Linux 2023 has it by default
- Try rebooting the instance
3. Outbound traffic blocked
- Session Manager needs outbound HTTPS
- Check Security Group allows all outbound
4. VPC endpoints missing (optional but helpful)
- For private-only access, you'd need SSM VPC endpoints
- Not required if NAT Gateway works
DNS resolution fails (nslookup doesn't work)
Possible causes:
1. NAT Gateway not working
- Fix NAT Gateway issue first (see ping troubleshooting)
2. DNS resolver not configured
- Amazon Linux uses VPC DNS by default
- Check
/etc/resolv.confhasnameserver 172.31.0.2
3. DHCP options set wrong (rare)
- VPC โ DHCP option sets
- Should use Amazon Provided DNS
curl returns "Could not resolve host"
This means DNS isn't working.
Check:
- Can you ping 8.8.8.8? (test raw internet)
- Can you run
nslookup google.com? (test DNS) - Is NAT Gateway working?
Usually caused by NAT Gateway or route table issues.
Tomorrow's previewโ
Today: You tested and proved your network works
Tomorrow (Day 9): We create the Application Load Balancer (ALB)
What we'll do:
The load balancer is you front door:
- Accepts HTTP/HTTPS traffic from the internet
- Routes it to your AI containers in private subnet
- Handles SSL termination (later)
- Provides a stable endpoint
Tomorrow we'll:
- Create a Target Group (defines where to send traffic)
- Create the Application Load Balancer
- Attach it to public subnets
- Configure listeners (HTTP on port 80)
- Attach ALB-SG for security
After Day 9, external traffic can reach your infrastructure.
What we learned todayโ
1. How to test infrastructure before deployingโ
Launch test instances to verify configuration
2. Session Manager for secure accessโ
No SSH keys, works with private subnets, browser-based
3. NAT Gateway validationโ
Private instances can reach internet via NAT
4. Routing verificationโ
Confirmed traffic flows through correct paths
5. The importance of cleanupโ
Delete test resources to avoid charges
The foundation is DONE
Days 1-2: Local development (your laptop) โ
Day 3: VPC (your territory) โ
Day 4: Subnets (front yards vs back yards) โ
Day 5: NAT Gateway (back gate) โ
Day 6: Route Tables (the roads) โ
Day 7: Security Groups (the smart locks) โ
Day 8: Test Your Network (validation) โ YOU ARE HERE โ
Day 9: Application Load Balancer
Days 10-12: DNS & SSL
Days 13-17: Deployment (Docker, ECS, production!)
Days 18-24: Features (API, frontend, polish)
Starting tomorrow, we build the application layer!
Share your progressโ
Tests passing? Network validated? Share it!
Twitter/X:
"Day 8: Tested my VPC network. Launched an instance in a private subnet, verified NAT Gateway works, confirmed routing is correct. Everything passes! Following @norahsakal's advent calendar ๐"
LinkedIn:
"Day 8 of building AI calling agents: Validated my network infrastructure. Launched a test EC2 instance, verified internet connectivity through NAT Gateway, and proved routing works. Network is production-ready!"
Tag me! I want to celebrate your progress! ๐
Want the full course?โ
But if you want:
โ
Complete codebase (one clean repo)
โ
Complete walkthroughs
โ
Support when stuck
โ
Production templates
โ
Advanced features
Join the waitlist for the full course (launching February 2026):
Let's chat about your use case!
Schedule a free call โ - no pitch, just two builders talking.
Tomorrow: Day 9 - Create your application load balancer ๐ข
Read Day 9 โ
See you then!
โ Norah
