Subnets and Routing Tables
What is a Subnet?
A subnet is a subdivision of your VPC. Each subnet exists in a single Availability Zone.
┌─────────────────────────────────────────────────────────────┐
│ SUBNETS │
├─────────────────────────────────────────────────────────────┤
│ │
│ VPC (10.0.0.0/16) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ REGION us-east-1 │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ AZ 1a │ │ AZ 1b │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │
│ │ │ │ │Subnet A │ │ │ │Subnet B │ │ │ │ │
│ │ │ │ │10.0.1.0 │ │ │ │10.0.2.0 │ │ │ │ │
│ │ │ │ │ /24 │ │ │ │ /24 │ │ │ │ │
│ │ │ │ └─────────┘ │ │ └─────────┘ │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Rule: 1 Subnet = 1 AZ (cannot span) │
│ But: 1 AZ can have multiple Subnets │
│ │
└─────────────────────────────────────────────────────────────┘
Public Subnet vs Private Subnet
┌─────────────────────────────────────────────────────────────┐
│ PUBLIC vs PRIVATE │
├─────────────────────────────────────────────────────────────┤
│ │
│ INTERNET │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ IGW │ │
│ └────┬─────┘ │
│ │ │
│ ┌─────────────────────┼─────────────────────┐ │
│ │ VPC │ │ │
│ │ │ │ │
│ │ ┌─────────────────┴───────────────┐ │ │
│ │ │ PUBLIC SUBNET │ │ │
│ │ │ │ │ │
│ │ │ • Route to IGW (0.0.0.0/0) │ │ │
│ │ │ • Auto-assigned public IP │ │ │
│ │ │ • Accessible from Internet │ │ │
│ │ │ │ │ │
│ │ │ Resources: Load Balancer, │ │ │
│ │ │ Bastion, NAT Gateway │ │ │
│ │ │ │ │ │
│ │ └─────────────────┬───────────────┘ │ │
│ │ │ │ │
│ │ │ (NAT Gateway) │ │
│ │ │ │ │
│ │ ┌─────────────────┴───────────────┐ │ │
│ │ │ PRIVATE SUBNET │ │ │
│ │ │ │ │ │
│ │ │ • NO route to IGW │ │ │
│ │ │ • No public IP │ │ │
│ │ │ • NOT accessible from Internet │ │ │
│ │ │ • Can exit via NAT │ │ │
│ │ │ │ │ │
│ │ │ Resources: App Servers, │ │ │
│ │ │ Database │ │ │
│ │ │ │ │ │
│ │ └──────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Key Differences
| Feature | Public Subnet | Private Subnet |
|---|---|---|
| Route to IGW | ✅ Yes (0.0.0.0/0 → igw) | ❌ No |
| Auto public IP | ✅ Activatable | ❌ No |
| Access from Internet | ✅ Possible | ❌ Impossible |
| Access to Internet | ✅ Direct | ⚠️ Via NAT Gateway |
| Use cases | Web servers, LB | DB, App servers |
Routing Tables
What is a Route Table?
A Route Table contains rules (routes) that determine where network traffic is directed.
┌─────────────────────────────────────────────────────────────┐
│ ROUTE TABLE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Route Table = "Direction sign" of the network │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Destination │ Target │ Result │ │
│ │ ─────────────────┼──────────────────┼────────────│ │
│ │ 10.0.0.0/16 │ local │ Stays VPC │ │
│ │ 0.0.0.0/0 │ igw-xxx │ Internet │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ How it works: │
│ 1. Packet arrives with destination 8.8.8.8 │
│ 2. Check: 8.8.8.8 in 10.0.0.0/16? No │
│ 3. Check: 8.8.8.8 in 0.0.0.0/0? Yes │
│ 4. Send to igw-xxx (Internet Gateway) │
│ │
│ Rule: Most specific route wins │
│ 10.0.0.0/16 is more specific than 0.0.0.0/0 │
│ │
└─────────────────────────────────────────────────────────────┘
Public vs Private Route Table
┌─────────────────────────────────────────────────────────────┐
│ PUBLIC vs PRIVATE ROUTE TABLE │
├─────────────────────────────────────────────────────────────┤
│ │
│ PUBLIC ROUTE TABLE │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Destination │ Target │ Description │ │
│ │─────────────────┼─────────────────┼─────────────────│ │
│ │ 10.0.0.0/16 │ local │ Internal traffic│ │
│ │ 0.0.0.0/0 │ igw-xxxxxxxx │ → Internet │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ PRIVATE ROUTE TABLE │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Destination │ Target │ Description │ │
│ │─────────────────┼─────────────────┼─────────────────│ │
│ │ 10.0.0.0/16 │ local │ Internal traffic│ │
│ │ 0.0.0.0/0 │ nat-xxxxxxxx │ → NAT Gateway │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ ISOLATED ROUTE TABLE (very private) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Destination │ Target │ Description │ │
│ │─────────────────┼─────────────────┼─────────────────│ │
│ │ 10.0.0.0/16 │ local │ Internal traffic│ │
│ │ (no 0.0.0.0/0) │ No Internet │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Subnet ↔ Route Table Association
┌─────────────────────────────────────────────────────────────┐
│ SUBNET - ROUTE TABLE ASSOCIATION │
├─────────────────────────────────────────────────────────────┤
│ │
│ Each subnet is associated with ONE Route Table │
│ │
│ ┌───────────────┐ │
│ │ Route Table │──────────┐ │
│ │ rtb-public │ │ │
│ └───────────────┘ │ │
│ │ │ │
│ │ ┌────▼────┐ │
│ ┌──────▼──────┐ │ Subnet │ │
│ │ Subnet │ │ 1b │ │
│ │ 1a │ │(public) │ │
│ │ (public) │ └─────────┘ │
│ └─────────────┘ │
│ │
│ ┌───────────────┐ │
│ │ Route Table │──────────┐ │
│ │ rtb-private │ │ │
│ └───────────────┘ │ │
│ │ │ │
│ │ ┌────▼────┐ │
│ ┌──────▼──────┐ │ Subnet │ │
│ │ Subnet │ │ 2b │ │
│ │ 2a │ │(private)│ │
│ │ (private) │ └─────────┘ │
│ └─────────────┘ │
│ │
│ Main Route Table: Default Route Table if not associated │
│ │
└─────────────────────────────────────────────────────────────┘
Create a Subnet
Via Console
1. VPC → Subnets → Create subnet
2. VPC: Select your VPC
3. Subnet name: public-1a
4. Availability Zone: us-east-1a
5. IPv4 CIDR block: 10.0.1.0/24
6. Create subnet
Via AWS CLI
# Create a public subnet
aws ec2 create-subnet \
--vpc-id vpc-xxx \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-1a}]'
# Enable auto-assign public IP (for public subnet)
aws ec2 modify-subnet-attribute \
--subnet-id subnet-xxx \
--map-public-ip-on-launch
Create and Configure a Route Table
Via AWS CLI
# Create a Route Table
aws ec2 create-route-table \
--vpc-id vpc-xxx \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=rtb-public}]'
# Add a route to Internet Gateway
aws ec2 create-route \
--route-table-id rtb-xxx \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-xxx
# Associate the subnet with the Route Table
aws ec2 associate-route-table \
--route-table-id rtb-xxx \
--subnet-id subnet-xxx
Recommended Addressing Plan
┌─────────────────────────────────────────────────────────────┐
│ RECOMMENDED ADDRESSING PLAN │
├─────────────────────────────────────────────────────────────┤
│ │
│ VPC: 10.0.0.0/16 (65,536 addresses) │
│ │
│ PUBLIC SUBNETS (Web Tier) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ public-1a : 10.0.1.0/24 (AZ a) - 251 IPs │ │
│ │ public-1b : 10.0.2.0/24 (AZ b) - 251 IPs │ │
│ │ public-1c : 10.0.3.0/24 (AZ c) - 251 IPs │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ PRIVATE SUBNETS (Application Tier) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ private-1a : 10.0.11.0/24 (AZ a) - 251 IPs │ │
│ │ private-1b : 10.0.12.0/24 (AZ b) - 251 IPs │ │
│ │ private-1c : 10.0.13.0/24 (AZ c) - 251 IPs │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ DATABASE SUBNETS (Data Tier) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ database-1a: 10.0.21.0/24 (AZ a) - 251 IPs │ │
│ │ database-1b: 10.0.22.0/24 (AZ b) - 251 IPs │ │
│ │ database-1c: 10.0.23.0/24 (AZ c) - 251 IPs │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Naming convention: │
│ • 10.0.X.0/24 where X = 1-9 for public │
│ • 10.0.X.0/24 where X = 11-19 for private app │
│ • 10.0.X.0/24 where X = 21-29 for database │
│ │
└─────────────────────────────────────────────────────────────┘
Best Practices
1. Always Multi-AZ
✅ GOOD: Subnets in at least 2 AZs
❌ BAD: All subnets in a single AZ
Reason: Resilience in case of an AZ failure
2. Separate Public and Private
✅ GOOD:
- Public subnets for Load Balancers
- Private subnets for application servers
- Isolated subnets for databases
❌ BAD: Everything in public subnets
3. Plan Addressing
✅ GOOD: Documented addressing plan before creation
❌ BAD: Random CIDR, possible overlaps
Tip: Leave space for growth
Summary
| Concept | Description |
|---|---|
| Subnet | Sub-network in an AZ |
| Public Subnet | Route to IGW, Internet access |
| Private Subnet | No IGW route, isolated |
| Route Table | Traffic direction rules |
| local | Automatic route for the VPC |
| 0.0.0.0/0 | Default route (Internet) |
Validation Quiz
- Can a subnet span multiple AZs?
- What makes a subnet "public"?
- Which route makes a subnet public?
- How many usable addresses in a /24?
- What is the Main Route Table?
Next section: Internet Gateway