YC

Learning cloud networking by building a multi-AZ VPC from scratch

CIDR subnetting, NAT routing, ALB target groups, and least-privilege IAM policies.

System: AWS Multi-Tier Networking & VPC Lab
Category: Cloud · AWS & Networking
Reading Time: 7 min read
Covered: AWS VPC · Subnets (Public/Private) · Route Tables · NAT Gateway · ALB · IAM
01. WHY I BUILT IT

The Trigger & Underlying Problem

The Trigger: I wanted to understand what actually happens when packets travel across cloud infrastructure instead of clicking through AWS default VPC wizards.

The Core Problem: I wanted to see a VPC with public and private subnets in two availability zones, instead of leaving everything in a default VPC. On the Expense Tracker diagram the frontend instances sit in the public subnets. The backend instances sit in the private app subnets.

Why Standard Solutions Were Insufficient: This was a deliberate learning lab designed to master subnet arithmetic, routing tables, and security group behaviors.

02. PRACTICAL IMPACT

What It Solves in Practice

PRACTICAL PROBLEM

A personal lab network: public subnets for the load balancer, NAT gateway, and frontend instances, and private subnets for the backend instances.

BENEFICIARIES

Provides a clean template for deploying microservices, APIs, and databases securely on AWS.

BEFORE THIS SYSTEM

Instances were launched in default VPCs with all ports open to 0.0.0.0/0.

03. IMPLEMENTATION

Architecture & Key Engineering Decisions

Created a custom 10.0.0.0/16 VPC spanning two Availability Zones in ap-south-1. Divided into two public subnets (/24) and two private subnets (/24).

Key Decisions:
  • Attached an Internet Gateway (IGW) to public subnets and provisioned a NAT Gateway with an Elastic IP in a public subnet for outbound-only private egress.
  • Separated route tables: the public route table routes 0.0.0.0/0 to the IGW; the private route table routes 0.0.0.0/0 to the NAT Gateway.
  • The architecture diagram draws an application load balancer across the public subnets, with frontend EC2 in those public subnets and backend EC2 in the private app subnets.
04. CHALLENGES & SOLUTIONS

What Failed in Practice & How It Was Addressed

WHAT WENT WRONG
  • EC2 instances in private subnets were unable to run `apt-get update` or reach GitHub because I forgot to associate the private subnet with the custom private route table.
  • Security group misconfiguration: ALB health checks returned 502 Bad Gateway because the EC2 security group only allowed traffic from my personal IP instead of the ALB security group ID.
  • Accidentally left a NAT Gateway running continuously over a weekend, generating surprise AWS egress charges.
HOW I SOLVED IT
  • Associated the private subnets explicitly with the private route table targeting the NAT Gateway.
  • Tightened the instance security group so ingress referenced the load balancer security group. The recording does not show the security group id, so I am not publishing one.
  • Created AWS budget billing alerts at $5 thresholds and scripted teardown procedures.
05. REFLECTION & LESSONS

Takeaways & Future Iterations

What I Learned:
  • Security groups are stateful (return traffic is automatically allowed); Network ACLs are stateless (both inbound and outbound rules must be explicitly allowed).
  • How to connect to private EC2 instances using AWS Systems Manager (SSM) Session Manager without needing a bastion host or open SSH port 22.
WHAT I WOULD CHANGE NOW:

I would codify the entire topology into Terraform modules with variables for CIDR blocks and AZ count rather than provisioning via the AWS console.