π AWS Session 9 β Amazon VPC
Private Networking Β· Subnets Β· Internet Gateway Β· Route Tables Β· Security Groups Β· NACLs Β· NAT Gateway
Part of my AWS learning journey β transitioning from Systems Engineer to Cloud/DevOps. VPC is the foundation everything else sits on β get this right and the rest of AWS networking clicks into place.
π Topics Covered
# Topic Type 1 Prerequisites β IP, Subnetting, Ports, DHCP, DNS Concept 2 What is a VPC β Big Picture Concept + Analogy 3 VPC as a Regional Resource Concept + Interview 4 RFC 1918 β Private IP Ranges Concept + Cert 5 CIDR Notation Concept + Lab 6 Default VPC vs Custom VPC Concept + Interview 7 VPC Tenancy β Shared vs Dedicated Concept + Cert 8 Subnets β Public vs Private Concept + Lab 9 Internet Gateway Concept + Lab 10 Route Tables Concept + Lab 11 Security Groups β Stateful Firewall Concept + Interview 12 NACLs β Stateless Firewall Concept + Interview 13 Stateful vs Stateless β Deep Explanation Concept + Cert 14 NAT Gateway β Private Subnet Internet Access Concept + Lab 15 How Traffic Flows β End to End Concept + DevOps 16 Lab β Build a VPC from Scratch Lab 17 Production VPC Architecture DevOps 18 Interview Questions Interview 19 Practice Tasks PracticeThe Big Picture First
Before any definition β here’s what VPC actually does in plain terms.
When you sign up for AWS, you’re sharing the same physical infrastructure as thousands of other companies. Without isolation, your servers could technically be reached by anyone else on that same hardware. VPC creates a logically isolated, private section of the AWS cloud that belongs only to you.
Think of it like this:
AWS is a massive co-working space with thousands of companies working in it. A VPC is your company’s private floor β locked doors, your own network, your own rules. Other companies are in the same building but cannot reach your floor. Inside your floor, you decide which rooms (subnets) are open to visitors (public) and which are staff-only (private).
The whiteboard diagram says it perfectly:
“VPC as a service provides you an isolated environment by default. But you can build connectivity using various components for your organisation.”
Prerequisites β Networking Foundations
You can’t truly understand VPC without these five concepts. Don’t skip them.
1. IP Address
An IP address is a unique logical address assigned to every device on a network so data knows where to go. Like a postal address β without it, packets have no destination.
IPv4 format: 192.168.1.100 (four numbers, 0-255, separated by dots)
IPv6 format: 2001:0db8:85a3::8a2e:0370:7334 (newer, longer, 128-bit)
In AWS VPC:
Every EC2 instance gets a private IP (e.g., 10.200.0.45)
Internet-facing instances get a public IP too
Elastic IP = static public IP that doesn't change on restart
Enter fullscreen mode Exit fullscreen mode
2. Subnetting
A VPC gives you a large block of IP addresses (e.g., 10.200.0.0/16 = 65,536 IPs). You wouldn’t hand all 65,536 addresses to random resources β you divide the VPC into subnets (smaller logical networks), each with its own range.
Why subnet?
- Security β isolate databases from web servers
- Organization β public-facing resources vs internal resources in separate segments
- IP conservation β allocate only what each tier needs
- AZ distribution β each subnet lives in one AZ
VPC: 10.200.0.0/16 (65,536 IPs total)
βββ Public Subnet: 10.200.0.0/24 (256 IPs) β web servers, ALB
βββ Private Subnet: 10.200.1.0/24 (256 IPs) β app servers
βββ Database Subnet: 10.200.2.0/24 (256 IPs) β RDS, databases
Enter fullscreen mode Exit fullscreen mode
3. Ports & Protocols
An IP address gets you to the right device. A port gets you to the right service on that device.
Request: 10.200.0.45 : 80 β reaches web server (Apache/Nginx)
Request: 10.200.0.45 : 22 β reaches SSH daemon
Request: 10.200.0.45 : 3306 β reaches MySQL database
Enter fullscreen mode Exit fullscreen mode
TCP vs UDP:
TCP UDP Connection Connection-oriented (handshake first) Connectionless (just send) Reliability Guarantees delivery, retries on failure No guarantee, no retry Speed Slower (overhead for reliability) Faster (no overhead) Use for HTTP, SSH, databases, email DNS, video streaming, gaming, VoIP4. DHCP β Automatic IP Assignment
Without DHCP, every device joining a network would need manual IP configuration. DHCP automates this through the DORA process:
D β Discover EC2 instance boots: "Is there a DHCP server?"
O β Offer DHCP server: "Here, take IP 10.200.0.45"
R β Request EC2: "Yes, I'll take that IP"
A β Acknowledge DHCP: "Confirmed. Here's your full config"
What DHCP delivers in AWS:
1. IP Address (e.g., 10.200.0.45)
2. Subnet Mask (e.g., 255.255.255.0)
3. Default Gateway (e.g., 10.200.0.1 β your VPC router)
4. Primary DNS (e.g., 169.254.169.253 β AWS DNS)
5. Secondary DNS (backup resolver)
Enter fullscreen mode Exit fullscreen mode
In AWS, the VPC’s built-in DHCP service handles all of this β EC2 instances get their config automatically at boot, no manual intervention.
5. DNS β The Internet’s Phonebook
DNS translates domain names to IP addresses. Without it, you’d type 54.239.28.85 instead of amazon.com.
You type: www.amazon.com
β
DNS resolver: "What's the IP for amazon.com?"
β
DNS server returns: 54.239.28.85
β
Your browser connects to 54.239.28.85
Enter fullscreen mode Exit fullscreen mode
In AWS VPC:
- Each VPC gets a built-in DNS resolver at
169.254.169.253(or VPC base IP + 2) - EC2 hostnames like
ip-10-200-0-45.ap-south-1.compute.internalare resolved automatically - Route 53 is AWS’s managed DNS service β used for custom domain names
What is a VPC β With the Whiteboard Diagram Explained
From your class diagram, here’s exactly what’s happening when a packet travels between two EC2 instances across VPCs:
VPC 1 (Source) VPC 2 (Destination)
βββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββ
β EC2 - OS (App/App) β β EC2 - OS (App/Dest) β
β β β β β β
β NITRO CARD - ENI β β NITRO CARD - ENI β
β (IP Address) β β (IP Address) β
β β β β β β
β SG Eval βββ Flow Logs β β SG (Inbound Rules) β Drop/ β
β Connection Tracking β β Accept β
ββββββββββββββββ¬βββββββββββββββ ββββββββββββββββ²βββββββββββββββ
β β
β Encapsulate β Overlay Tunnel β Decapsulate
βββββββββββββββββββββββββββββββββββββββββββββ
VPC is MAPPED to:
βββ Subnet A (NACL = Enforcement Point)
βββ Subnet B
Enter fullscreen mode Exit fullscreen mode
Walking through this step by step:
- EC2 OS generates a packet destined for the other VPC’s IP
- NITRO Card + ENI β AWS’s custom hardware that handles networking. The ENI (Elastic Network Interface) is the virtual network card attached to the EC2
- Security Group evaluation β before the packet leaves, SG rules are checked (outbound). Flow logs record the traffic. Connection tracking remembers this connection
- Encapsulation β the packet is wrapped in another packet (overlay tunnel) and sent across the AWS backbone network
- Decapsulation β at destination, the outer wrapper is removed
- NACL enforcement β at the subnet boundary of the destination VPC, the NACL evaluates whether to allow or drop the inbound traffic
- Security Group β at the destination ENI, inbound SG rules evaluated
- EC2 OS receives the packet
VPC as a Regional Resource
AWS Account
β
βββ Region: ap-south-1 (Mumbai)
β βββ VPC 1 (10.0.0.0/16)
β β βββ AZ: ap-south-1a β Subnet A (10.0.1.0/24)
β β βββ AZ: ap-south-1b β Subnet B (10.0.2.0/24)
β β βββ AZ: ap-south-1c β Subnet C (10.0.3.0/24)
β β
β βββ VPC 2 (10.200.0.0/16) β separate VPC, same region
β
βββ Region: us-east-1 (N. Virginia)
βββ VPC 3 (10.1.0.0/16) β must be separate VPC for cross-region
Enter fullscreen mode Exit fullscreen mode
Key rules:
- A VPC belongs to exactly one Region β it cannot span Regions
- A VPC can span multiple AZs within that Region via subnets
- Cross-Region networking: use VPC Peering (direct 1:1) or Transit Gateway (hub-and-spoke for many VPCs)
- Default limit: 5 VPCs per Region (soft limit, can request increase via Service Quotas)
π― Interview scenario: “A customer says they cannot create a new VPC.” β Check if they’ve hit the 5 VPC per Region quota. Go to Service Quotas β request increase, or delete unused VPCs. Always check the specific Region they’re trying to create in β limits are per-Region.
RFC 1918 β Private IP Ranges
Not all IP addresses are created equal. RFC 1918 (defined by IETF) reserves three ranges specifically for private networks β they are never routed on the public internet.
Range CIDR Block Total IPs Common Use
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
10.0.0.0 - 10.255.255.255 10.0.0.0/8 16,777,216 Large enterprise VPCs
172.16.0.0 - 172.31.255.255 172.16.0.0/12 1,048,576 Medium networks
192.168.0.0 - 192.168.255.255 192.168.0.0/16 65,536 Home routers, small offices
Enter fullscreen mode Exit fullscreen mode
These are the only IP ranges you should use for VPC CIDR blocks in AWS.
Why? Because private IPs are not routable on the internet β two companies can both use 10.0.0.0/16 internally without conflict, since those IPs never appear on the public internet.
β οΈ Overlap trap: If two VPCs you want to peer have overlapping CIDR blocks (e.g., both use
10.0.0.0/16), you cannot peer them. Plan CIDR ranges carefully upfront in multi-VPC architectures.
CIDR Notation β Reading IP Ranges
CIDR (Classless Inter-Domain Routing) is how IP ranges are written. Understanding the / notation is essential.
10.200.0.0/16
10.200.0.0 = the starting IP address
/16 = 16 bits are fixed (the "network" part)
remaining 32-16 = 16 bits are flexible (the "host" part)
2^16 = 65,536 total IP addresses in this range
Enter fullscreen mode Exit fullscreen mode
Quick reference:
CIDR IPs Available Use Case /16 65,536 Entire VPC (large) /24 256 One subnet /28 16 Small subnet (minimum for AWS) /32 1 Single specific IP (used in rules) /0 All IPs “Anywhere” (used in internet routes)AWS reserves 5 IPs in every subnet:
10.200.0.0 β Network address
10.200.0.1 β VPC router (your default gateway)
10.200.0.2 β DNS resolver
10.200.0.3 β Reserved for future use
10.200.0.255 β Broadcast address
So a /24 subnet = 256 - 5 = 251 usable IPs
Enter fullscreen mode Exit fullscreen mode
π― Cert tip: AWS always takes 5 IPs per subnet. Exam questions sometimes ask how many usable hosts are in a /28 subnet β answer is 16 – 5 = 11.
Default VPC vs Custom VPC
Default VPC Custom VPC Created by AWS automatically, one per Region You create manually CIDR 172.31.0.0/16 (always) Your choice (RFC 1918) Subnets One public subnet per AZ (pre-created) You design and create Internet Gateway Pre-attached You create and attach Route tables Pre-configured with internet route You configure Public IPs Auto-assigned to all instances You choose per subnet Use for Quick learning, quick testing Production, all real workShould you delete the Default VPC?
Many organisations delete it or leave it deliberately empty. Why? If developers can accidentally launch resources into the Default VPC (which has public internet access by default), they may expose things that should be private. Custom VPCs enforce intentional network design.
π― Production standard: In real companies, the Default VPC is disabled or deleted. All production infrastructure runs in Custom VPCs with carefully designed subnet tiers, dedicated security groups per tier, and explicit routing.
VPC Tenancy β Shared vs Dedicated
Default Tenancy (Shared):
Your EC2 instances run on physical hardware shared with other AWS customers. The hypervisor (Nitro) provides full isolation β other customers cannot see your data β but the underlying physical server is shared.
Dedicated Tenancy:
Your EC2 instances run on physical hardware that no other AWS customer uses. The server is yours alone.
Default Tenancy: [Your VM] [Other Customer VM] [Another VM] β same physical server
β β β
ββββββββββββ΄βββββββββββββββββββ
Nitro hypervisor isolates them
Dedicated Tenancy: [Your VM] [Your VM] [Your VM] β entire server is yours
No other customers on this hardware
Enter fullscreen mode Exit fullscreen mode
When to use Dedicated:
- Regulatory compliance requiring physical isolation (HIPAA, PCI-DSS)
- Software licensing tied to physical cores/sockets
- Security policy mandating dedicated hardware
Cost: Significantly more expensive than Default. Most workloads don’t need it.
β οΈ One-way door: A VPC can be changed from Default β Dedicated tenancy. But Dedicated β Default cannot be changed back. If you want Default tenancy again, you must create a new VPC and migrate everything. Always think carefully before choosing Dedicated.
Subnets β Public vs Private
A subnet is a subdivision of your VPC β a smaller network within the larger network. What makes a subnet “public” or “private” isn’t a setting you click β it’s determined by the route table attached to it.
A subnet is PUBLIC if:
β Its route table has a route: 0.0.0.0/0 β Internet Gateway
β Instances can send/receive internet traffic
β Instances should have a public IP (or Elastic IP)
A subnet is PRIVATE if:
β Its route table has NO route to an Internet Gateway
β No direct internet access
β For private subnet internet access β needs NAT Gateway
Enter fullscreen mode Exit fullscreen mode
Standard 3-tier architecture:
VPC: 10.200.0.0/16
β
βββ Public Subnet: 10.200.0.0/24 (AZ-a)
β Route: 0.0.0.0/0 β IGW
β Resources: ALB, Bastion Host, NAT Gateway
β
βββ Private Subnet: 10.200.1.0/24 (AZ-a)
β Route: 0.0.0.0/0 β NAT Gateway
β Resources: EC2 App Servers
β
βββ Database Subnet: 10.200.2.0/24 (AZ-a)
Route: local only
Resources: RDS, ElastiCache
No internet access at all
Enter fullscreen mode Exit fullscreen mode
π‘ Why keep databases in a separate subnet with no internet route? Even if someone compromises your app server, the database is in a completely separate network segment with no path to the internet. Lateral movement is constrained.
Internet Gateway (IGW)
An Internet Gateway is the door between your VPC and the public internet. Without it, nothing in your VPC can reach the internet and nothing from the internet can reach your VPC.
Internet
β
Internet Gateway (IGW)
β β attached to VPC (1:1 relationship)
β
VPC
Enter fullscreen mode Exit fullscreen mode
Key facts:
- One VPC can have only one IGW
- Horizontally scaled, redundant, and highly available β managed entirely by AWS
- No bandwidth limits, no performance configuration needed
- Free β you pay for data transfer, not the gateway itself
- Performs NAT for public IPv4 β maps public IP to private IP for inbound traffic
Traffic flow for a public EC2 instance:
Internet user (203.0.113.5) β requests http://54.239.28.85 (EC2 public IP)
β
Internet Gateway receives request
β
IGW translates: 54.239.28.85 β 10.200.0.45 (EC2 private IP)
β
Routes to EC2 instance in public subnet
β
EC2 processes request, sends response
β
Response goes back through IGW (private IP β public IP translation)
β
Internet user receives response
Enter fullscreen mode Exit fullscreen mode
Route Tables
A route table is a set of rules (routes) that determines where network traffic is directed. Every subnet must be associated with a route table β this is what makes it public or private.
How to read a route table:
Public Subnet Route Table:
Destination Target
10.200.0.0/16 local β all VPC-internal traffic stays inside
0.0.0.0/0 igw-xxxxx β all other traffic goes to Internet Gateway
Private Subnet Route Table:
Destination Target
10.200.0.0/16 local β VPC-internal traffic stays inside
0.0.0.0/0 nat-xxxxx β internet traffic goes through NAT Gateway
(NAT in public subnet bridges to IGW)
Database Subnet Route Table:
Destination Target
10.200.0.0/16 local β only internal VPC traffic allowed
no 0.0.0.0/0 route = no internet at all
Enter fullscreen mode Exit fullscreen mode
Most specific route wins:
Traffic to 10.200.1.50:
Match: 10.200.0.0/16 β local (/16 matches)
No match for 0.0.0.0/0 needed
β stays inside VPC β
Traffic to 8.8.8.8 (Google DNS):
No match for 10.200.0.0/16 (8.8.8.8 is not in this range)
Match: 0.0.0.0/0 β IGW (catch-all)
β goes to internet via IGW β
Enter fullscreen mode Exit fullscreen mode
π‘ One Main Route Table: Every VPC has a main route table (implicitly attached to all subnets by default). You create custom route tables and explicitly associate them with specific subnets to override the main table. Always use custom route tables per subnet tier β never rely on the main table for production routing.
Security Groups β Stateful Firewall
A Security Group is a stateful virtual firewall that controls traffic at the ENI level β attached to EC2 instances, RDS databases, and Load Balancers.
Analogy: The SG is the lock on an employee’s cabin door. Only people on the approved list get in. And because it’s stateful, if the employee walks out to get coffee (outbound), they’re automatically let back in (return traffic) β no separate rule needed.
Key behaviours:
Default rules:
Inbound: DENY all (nothing gets in unless you explicitly allow it)
Outbound: ALLOW all (everything can leave by default)
Stateful = tracks connections:
Outbound rule allows EC2 to call Google (port 443)
β Return traffic from Google is automatically allowed
β No inbound rule needed for the response
Enter fullscreen mode Exit fullscreen mode
Important limitations:
- Security Groups can only ALLOW β they cannot explicitly deny specific IPs
- If you want to block a specific IP, you need a NACL (covered next)
- A Security Group cannot be applied to a VPC β only to resources (ENIs)
- Multiple SGs can be attached to one resource (rules are combined)
- SGs can reference other SGs as source (e.g., allow traffic from SG-ALB)
NACLs β Stateless Firewall
A NACL (Network Access Control List) is a stateless firewall at the subnet boundary β it evaluates traffic entering and leaving a subnet before it even reaches any EC2 instance.
Analogy: The NACL is the security guard at the department entrance (subnet boundary). Before anyone enters the department, the guard checks them against a list. The guard doesn’t care if someone is “already inside” β every time they pass through the door, they’re checked again.
Internet traffic
β
NACL Inbound Rules (evaluated at subnet entry)
β (if allowed)
EC2 Instance (Security Group evaluated at ENI)
β (response)
NACL Outbound Rules (evaluated at subnet exit)
β (if allowed)
Internet
Enter fullscreen mode Exit fullscreen mode
NACL rules have numbered priorities β lower number = evaluated first:
Rule # Protocol Port Source Allow/Deny
100 TCP 80 0.0.0.0/0 ALLOW β HTTP allowed
110 TCP 443 0.0.0.0/0 ALLOW β HTTPS allowed
120 TCP 22 10.200.0.0/16 ALLOW β SSH from VPC only
* ALL ALL 0.0.0.0/0 DENY β default: deny everything else
Enter fullscreen mode Exit fullscreen mode
The * rule at the bottom is the catch-all deny β always present, cannot be modified.
Stateful vs Stateless β The Critical Difference
This is one of the most tested concepts in AWS certs and a very common interview question.
Security Group (Stateful) NACL (Stateless) Tracks connections? β Yes β No Return traffic Auto-allowed Must explicitly allow Applied at ENI (instance level) Subnet boundary Rules Allow only Allow + Deny Rule evaluation All rules evaluated together In order, first match wins Scope Per-resource Per-subnet (all resources in subnet) Default Deny all inbound, Allow all outbound Allow all (default NACL)The stateful vs stateless scenario that always appears in exams:
EC2 in public subnet makes an outbound HTTPS call to api.example.com (port 443)
Security Group evaluation:
Outbound rule: TCP 443 β ALLOW β
Return traffic (inbound from api.example.com): AUTO-ALLOWED β
(Stateful β tracks the connection, no explicit inbound rule needed)
NACL evaluation (outbound request):
Outbound rule: TCP 443 β ALLOW β
Return traffic comes back on EPHEMERAL PORT (1024-65535)
NACL inbound rule needed: TCP 1024-65535 β ALLOW β
(Stateless β doesn't remember the connection, must explicitly allow return traffic)
Enter fullscreen mode Exit fullscreen mode
π― Classic exam question: “An EC2 can send requests but cannot receive responses. Security Group allows outbound TCP 443. NACL allows outbound TCP 443. What’s wrong?” β The NACL is missing an inbound rule for ephemeral ports (1024-65535) for the return traffic. Security Groups don’t need it (stateful). NACLs do (stateless).
Ephemeral ports: When your EC2 makes an outbound connection to port 443, the response comes back on a randomly assigned ephemeral port (1024-65535). NACLs need an explicit rule to allow this return range. Security Groups handle it automatically.
NAT Gateway β Private Subnet Internet Access
Private subnets have no direct path to the internet β that’s intentional. But sometimes private instances need internet access outbound: to download software updates (yum update), reach external APIs, or pull container images.
NAT = Network Address Translation
A NAT Gateway sits in the public subnet and acts as a proxy β private instances send traffic to it, it forwards to the internet using its own public IP, gets the response, and sends it back to the private instance.
Analogy: A NAT Gateway is like a receptionist. Internal staff (private EC2) can ask the receptionist to call a vendor (internet service) on their behalf. The vendor speaks only to the receptionist (public IP), never knowing the internal staff member’s internal extension (private IP). The receptionist takes the response and passes it back inside.
How it works β step by step:
Private EC2 (10.200.1.45) wants to run: yum update
Step 1: EC2 sends packet
Source: 10.200.1.45 (private IP)
Destination: 151.101.1.91 (yum repo server on internet)
Step 2: Route table sends to NAT Gateway
Private subnet route: 0.0.0.0/0 β nat-gateway-id
Step 3: NAT Gateway translates
Replaces source: 10.200.1.45 β 52.66.1.100 (NAT Gateway's Elastic IP)
Forwards to internet via IGW
Step 4: Response comes back
Source: 151.101.1.91 (yum server)
Destination: 52.66.1.100 (NAT Gateway public IP)
Step 5: NAT Gateway translates back
Looks up connection table: 52.66.1.100 β 10.200.1.45
Sends response to private EC2
Step 6: Private EC2 receives yum update packages β
Internet never knew the real private IP
No unsolicited inbound from internet possible
Enter fullscreen mode Exit fullscreen mode
Many-to-one NAT:
Multiple private instances can all share one NAT Gateway’s public IP:
10.200.1.10 β outbound β 52.66.1.100 (NAT EIP)
10.200.1.11 β outbound β 52.66.1.100 (NAT EIP)
10.200.1.12 β outbound β 52.66.1.100 (NAT EIP)
Enter fullscreen mode Exit fullscreen mode
The NAT Gateway tracks each connection in its translation table so return traffic goes to the correct private instance. The internet sees only one public IP.
NAT Gateway vs NAT Instance:
NAT Gateway (AWS Managed) NAT Instance (DIY on EC2) Management Fully managed by AWS You manage (OS, updates) Availability Highly available within AZ Single point of failure Bandwidth Up to 100 Gbps Limited by instance type Cost Higher per hour Lower per hour Production use β Always β Avoidβ Always use NAT Gateway in production β never NAT Instance. The management overhead and single-point-of-failure risk of NAT Instance outweigh the cost savings.
π° Cost note: NAT Gateway charges per hour + per GB of data processed. Put NAT Gateway in each AZ (not just one) for high availability β but this doubles the NAT cost. Trade-off between cost and availability.
End-to-End Traffic Flow β How It All Works Together
Scenario: A user in Mumbai opens your website hosted on a private EC2 behind an ALB.
User Browser (Mumbai)
β
β HTTPS request to your domain
βΌ
Route 53 (DNS)
β resolves domain β ALB DNS name β ALB IP
βΌ
Internet Gateway (IGW)
β traffic enters VPC
βΌ
NACL (Public Subnet boundary)
β inbound rule: TCP 443 β ALLOW
βΌ
Application Load Balancer (in Public Subnet)
β SG-ALB: allows TCP 443 from 0.0.0.0/0
β ALB decrypts HTTPS, picks healthy EC2 target
βΌ
NACL (Private Subnet boundary)
β inbound rule: TCP 8080 from VPC CIDR β ALLOW
βΌ
EC2 App Server (in Private Subnet)
β SG-EC2: allows TCP 8080 from SG-ALB only
β App processes request, queries database
βΌ
RDS Database (in DB Subnet)
β SG-RDS: allows TCP 3306 from SG-EC2 only
β Returns query results
βΌ
Response travels back up the same path β
Enter fullscreen mode Exit fullscreen mode
This is the standard 3-tier architecture deployed in every serious production environment.
Lab β Build a VPC from Scratch
This is exactly what you did in class. Walk through it again to make the steps click.
What You’re Building
VPC: 10.200.0.0/16
βββ Public Subnet: 10.200.0.0/24 (connected to IGW)
βββ Private Subnet: 10.200.1.0/24 (connected to NAT GW)
βββ Internet Gateway (attached to VPC)
βββ NAT Gateway (in public subnet)
βββ Public Route Table (0.0.0.0/0 β IGW)
βββ Private Route Table (0.0.0.0/0 β NAT GW)
Enter fullscreen mode Exit fullscreen mode
Step 1 β Create VPC
VPC Console β Your VPCs β Create VPC
Resource: VPC only (not "VPC and more")
Name tag: lab-vpc
IPv4 CIDR: 10.200.0.0/16 (manual input)
IPv6 CIDR: No
Tenancy: Default
β Create VPC
Enter fullscreen mode Exit fullscreen mode
β
Checkpoint: lab-vpc appears in Your VPCs list with state Available
Step 2 β Create Subnets
Public Subnet:
Subnets β Create subnet
VPC: lab-vpc
Subnet name: public-subnet-1
Availability Zone: ap-south-1a
IPv4 CIDR block: 10.200.0.0/24
β Create subnet
Enter fullscreen mode Exit fullscreen mode
Private Subnet:
Subnet name: private-subnet-1
Availability Zone: ap-south-1b
IPv4 CIDR block: 10.200.1.0/24
Enter fullscreen mode Exit fullscreen mode
π‘ Put public and private subnets in different AZs β this improves availability. Even if one AZ has issues, the other tier keeps running.
β Checkpoint: Both subnets appear, status Available
Step 3 β Create Internet Gateway
Internet Gateways β Create internet gateway
Name tag: lab-igw
β Create
β After creation: Actions β Attach to VPC β select lab-vpc β Attach
Enter fullscreen mode Exit fullscreen mode
β οΈ After creating an IGW, it shows “Detached” until you attach it to a VPC. This is the step most beginners forget β the IGW exists but does nothing until attached.
β
Checkpoint: lab-igw shows state Attached to lab-vpc
Step 4 β Create Route Tables
Public Route Table:
Route Tables β Create route table
Name: public-rt
VPC: lab-vpc β Create
Edit Routes:
Add route:
Destination: 0.0.0.0/0
Target: lab-igw
Save routes
Subnet Associations β Edit subnet associations:
Select: public-subnet-1
Save
Enter fullscreen mode Exit fullscreen mode
Private Route Table (add after NAT Gateway is created):
Route Tables β Create route table
Name: private-rt
VPC: lab-vpc β Create
(Add 0.0.0.0/0 β NAT Gateway after Step 5)
Subnet Associations β Edit subnet associations:
Select: private-subnet-1
Save
Enter fullscreen mode Exit fullscreen mode
Step 5 β Create NAT Gateway
NAT Gateways β Create NAT gateway
Name: lab-nat-gw
Subnet: public-subnet-1 β MUST be in public subnet
Connectivity type: Public
Elastic IP: Allocate Elastic IP β Allocate
β Create NAT gateway
Wait 2-3 minutes for state: Available
Enter fullscreen mode Exit fullscreen mode
β οΈ NAT Gateway must be in the public subnet β it needs internet access via the IGW to forward traffic on behalf of private instances.
Now update private route table:
private-rt β Routes β Edit routes
Add route:
Destination: 0.0.0.0/0
Target: lab-nat-gw
Save routes
Enter fullscreen mode Exit fullscreen mode
Step 6 β Launch EC2 Instances to Test
Public EC2:
EC2 β Launch Instance
Name: public-ec2
AMI: Amazon Linux 2023
Type: t2.micro
VPC: lab-vpc
Subnet: public-subnet-1
Auto-assign public IP: Enable
Security Group: allow SSH (22) from My IP + HTTP (80) from anywhere
Enter fullscreen mode Exit fullscreen mode
Private EC2:
Name: private-ec2
VPC: lab-vpc
Subnet: private-subnet-1
Auto-assign public IP: Disable β no public IP
Security Group: allow SSH (22) from VPC CIDR (10.200.0.0/16)
Enter fullscreen mode Exit fullscreen mode
Testing connectivity:
# SSH into public EC2 (has public IP)
ssh -i key.pem ec2-user@<public-ec2-public-ip>
# From public EC2, SSH into private EC2 (using private IP)
ssh -i key.pem ec2-user@<private-ec2-private-ip>
# From private EC2, test internet access via NAT Gateway
curl https://checkip.amazonaws.com
# Returns: NAT Gateway's Elastic IP (not the private EC2's IP) β
# Test outbound (yum update should work)
sudo yum update -y # downloads via NAT Gateway β
Enter fullscreen mode Exit fullscreen mode
π’ Production VPC Architecture
This is what a real company’s VPC looks like in AWS. Understanding this at the architecture level is what separates someone who knows AWS features from someone who can design AWS systems.
Region: ap-south-1 (Mumbai)
VPC: prod-vpc 10.0.0.0/16
β
βββ AZ: ap-south-1a AZ: ap-south-1b
β βββ Public Subnet 10.0.0.0/24 Public Subnet 10.0.10.0/24
β β βββ ALB node βββ ALB node
β β βββ NAT Gateway βββ NAT Gateway
β β
β βββ Private App Subnet 10.0.1.0/24 Private App Subnet 10.0.11.0/24
β β βββ EC2 (App Server) βββ EC2 (App Server)
β β ASG manages these ASG manages these
β β
β βββ Private DB Subnet 10.0.2.0/24 Private DB Subnet 10.0.12.0/24
β βββ RDS Primary βββ RDS Standby (Multi-AZ)
β
βββ Internet Gateway (single, attached to VPC)
βββ Route 53 (DNS β ALB)
βββ CloudFront (CDN β ALB or S3)
Security controls:
SG-ALB: HTTP/HTTPS from 0.0.0.0/0
SG-EC2: HTTP from SG-ALB only
SG-RDS: MySQL (3306) from SG-EC2 only
NACL-Public: Allow 80, 443, 1024-65535 inbound; Allow all outbound
NACL-Private: Allow from VPC CIDR; No direct internet
Enter fullscreen mode Exit fullscreen mode
Why this design?
- Users only ever reach the ALB β EC2 and RDS are never exposed to internet
- Even if app servers are compromised, no direct database access from internet
- Multi-AZ for everything β if one AZ goes down, the other keeps serving
- NAT Gateways in each AZ β private instances don’t go cross-AZ for internet (reduces cost and latency)
β‘ Quick Revision
VPC FUNDAMENTALS
Regional resource β one Region, spans multiple AZs via subnets
Default limit: 5 VPCs per Region (soft limit)
CIDR must be from RFC 1918 private ranges
Overlapping CIDRs = cannot peer VPCs
SUBNET
One AZ per subnet (subnet lives in one AZ)
Public = route table has 0.0.0.0/0 β IGW
Private = route table has 0.0.0.0/0 β NAT GW (or no internet route)
AWS reserves 5 IPs per subnet
INTERNET GATEWAY
One IGW per VPC (1:1 relationship)
Must attach to VPC after creating
Provides internet access for public subnets
Performs NAT for public IPs
ROUTE TABLE
Controls where traffic goes
Most specific route wins
Each subnet must have one associated route table
Local route (VPC CIDR) always present, cannot delete
SECURITY GROUP (Stateful)
Operates at ENI / instance level
Tracks connections β return traffic auto-allowed
Allow rules only (cannot deny specific IPs)
Default: deny all inbound, allow all outbound
NACL (Stateless)
Operates at subnet boundary
Numbered rules, evaluated in order (lowest first)
Must allow BOTH directions (including return/ephemeral ports 1024-65535)
Allow + Deny rules
Default NACL: allow all
NAT GATEWAY
Must be in public subnet + has Elastic IP
Private instances β NAT GW β IGW β Internet
Outbound only from private instances (no unsolicited inbound)
Many private IPs share one public IP
Always use NAT Gateway (not NAT Instance) in production
DHCP (DORA)
Discover β Offer β Request β Acknowledge
Gives: IP, Subnet Mask, Default Gateway, DNS servers
STATEFUL vs STATELESS
Stateful (SG): tracks connection, return traffic auto-allowed
Stateless (NACL): no memory, both directions need explicit rules
Enter fullscreen mode Exit fullscreen mode
πΌ Interview Questions
Q1: What is the difference between a Security Group and a NACL?
Security Groups are stateful firewalls at the ENI/instance level β they track connections so return traffic is automatically allowed, and they support Allow rules only. NACLs are stateless firewalls at the subnet boundary β they don’t track connections so you need explicit rules for both directions (including ephemeral ports for return traffic), and they support both Allow and Deny rules.
Q2: A private EC2 instance can send requests to the internet but cannot receive responses. What’s likely wrong?
The NACL for the private subnet is missing an inbound rule for ephemeral ports (1024-65535). The request goes out fine, but the response comes back on a dynamically assigned port in this range. The Security Group doesn’t need a rule (stateful), but the NACL does (stateless). Add NACL inbound rule: TCP 1024-65535 from 0.0.0.0/0.
Q3: A customer says they cannot create a new VPC. What do you check first?
Check if they’ve hit the VPC quota for that Region β the default is 5 VPCs per Region. Go to Service Quotas and request an increase, or identify and delete unused VPCs. Also confirm they’re checking the correct Region.
Q4: What makes a subnet “public” vs “private” in AWS?
Not a setting β it’s determined by the route table. A subnet is public if its route table contains a route sending 0.0.0.0/0 traffic to an Internet Gateway. A subnet is private if it has no such route (or routes internet traffic through a NAT Gateway instead).
Q5: Why must a NAT Gateway be placed in a public subnet?
The NAT Gateway needs to be reachable from the internet to forward traffic on behalf of private instances. It must itself have a path to the Internet Gateway, which only exists in public subnets (via the route table). If it were in a private subnet, it would have no internet path and couldn’t perform its function.
Q6: Can two VPCs with CIDR 10.0.0.0/16 be peered?
No. VPC Peering requires non-overlapping CIDR blocks. Both VPCs using 10.0.0.0/16 means their IP ranges are identical β routing would be ambiguous. You’d need to change one VPC’s CIDR (which requires recreation) or use a different range from the start. This is why planning CIDR blocks upfront in multi-VPC architectures is critical.
Q7: What is the difference between an Internet Gateway and a NAT Gateway?
An Internet Gateway enables two-way communication between public subnet resources and the internet β inbound and outbound. A NAT Gateway enables outbound-only internet access for private subnet resources β it translates private IPs to its public IP for outbound traffic but blocks all unsolicited inbound connections from the internet.
π¬ Practice Tasks
Build from scratch (mandatory): Without referring to the lab steps, create a complete VPC: custom CIDR, one public and one private subnet in different AZs, IGW attached, NAT Gateway in public subnet, separate route tables per subnet with correct routes. Launch one EC2 in each subnet and verify: public EC2 reachable from internet, private EC2 reachable only from public EC2 via SSH, private EC2 can reach internet via NAT.
NACL test: Create a NACL that blocks HTTP (port 80) inbound to a public subnet but allows HTTPS (443). Launch an EC2 with Apache. Confirm HTTP is blocked but HTTPS works.
VPC Flow Logs: Enable VPC Flow Logs on your VPC. Generate some traffic (SSH, HTTP). Find the logs in CloudWatch and identify: source IP, destination IP, port, and whether traffic was accepted or rejected.
Stateless gotcha: Launch a private EC2 with a custom NACL that allows TCP 443 outbound. Try to reach an HTTPS endpoint. It will fail. Figure out why (missing ephemeral port inbound rule). Fix it and confirm it works.
Multi-AZ setup: Create subnets in 2 AZs, one public + one private in each AZ. Place a NAT Gateway in each public subnet. Configure private subnets to use the NAT Gateway in their own AZ. Test that private instances in each AZ reach the internet through their local NAT (check source IP).
AWS Session 9 β VPC Essentials | Cloud + DevOps learning journey β Systems Engineer β Cloud/DevOps Engineer
λ΅κΈ λ¨κΈ°κΈ°