Skip to main content
Current1mo ago

🌐 AWS VPC — Complete Reference Guide

What is a VPC? Your own isolated private network inside AWS. Think of it as your private data center in the cloud. Nothing gets in or out unless you explicitly allow it.


📌 Table of Contents

  1. Core Concepts

  2. VPC Architecture Diagram

  3. Key Components Deep Dive

  4. CIDR Blocks & IP Addressing

  5. Subnets

  6. Internet Gateway (IGW)

  7. NAT Gateway

  8. Route Tables

  9. Security Groups

  10. Network ACLs (NACLs)

  11. VPC Endpoints

  12. VPC Peering & Transit Gateway

  13. Traffic Flow Example (Redash Setup)

  14. Common Architecture Patterns

  15. Cost Breakdown

  16. Best Practices Checklist

  17. Common Mistakes & Troubleshooting

  18. Useful Links & Resources


🧠 Core Concepts

A VPC gives you full control over your virtual networking environment including IP address ranges, subnets, route tables, and gateways.

Key facts:

  • A VPC exists within a single AWS Region

  • A VPC can span multiple Availability Zones (AZs)

  • Each AWS account gets a default VPC per region (ready to use out of the box)

  • The VPC itself is free — but some components (NAT Gateway, VPC Endpoints) cost money

  • You can create multiple VPCs per region (default limit: 5, can request increase)


🏗 VPC Architecture Diagram

Internet


┌──────────────────────────────────────────────────────────┐
│ VPC (172.16.0.0/16) │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ PUBLIC SUBNET (172.16.1.0/24) │ │
│ │ - Has route to Internet Gateway │ │
│ │ - Resources CAN have public IPs │ │
│ │ - ALB (Load Balancer) lives here │ │
│ │ - ECS tasks live here (if no NAT Gateway) │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ▼ (security group allows) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ PRIVATE SUBNET (172.16.2.0/24) │ │
│ │ - NO route to Internet Gateway │ │
│ │ - Resources CANNOT reach internet directly │ │
│ │ - RDS databases live here │ │
│ │ - Redis / ElastiCache lives here │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘


🔑 Key Components Deep Dive

ComponentWhat It DoesAnalogy
VPCYour isolated network in AWSYour private data center
SubnetA range of IPs within the VPC, in one AZRooms in your data center
Internet GatewayConnects VPC to the public internetThe front door
NAT GatewayLets private resources access internet (outbound only)A one-way mail slot
Route TableDefines where traffic goesRoad signs
Security GroupStateful firewall per resource (instance-level)A personal bodyguard
NACLStateless firewall per subnetA building security gate
VPC EndpointPrivate connection to AWS services without internetInternal hallway to another building
Elastic IPA static public IPv4 addressA fixed phone number

🔢 CIDR Blocks & IP Addressing

CIDR (Classless Inter-Domain Routing) defines the IP range for your VPC.

Common VPC CIDR blocks:

CIDR BlockIP RangeTotal IPsUse Case
10.0.0.0/1610.0.0.0 – 10.0.255.25565,536Large production VPC
172.16.0.0/16172.16.0.0 – 172.16.255.25565,536Standard VPC
192.168.0.0/16192.168.0.0 – 192.168.255.25565,536Smaller environments
10.0.0.0/2410.0.0.0 – 10.0.0.255256Single small subnet

Quick CIDR math:

  • /16 = 65,536 IPs

  • /20 = 4,096 IPs

  • /24 = 256 IPs

  • /28 = 16 IPs (smallest allowed in AWS)

Rules:

  • VPC CIDR range: /16 (largest) to /28 (smallest)

  • AWS reserves 5 IPs in every subnet (first 4 + last 1)

  • Don't overlap CIDR ranges if you plan to peer VPCs or connect on-premises


🏠 Subnets

A subnet is a range of IPs within your VPC, placed in one specific Availability Zone.

Public vs Private — the only real difference

FeaturePublic SubnetPrivate Subnet
Route to Internet Gateway✅ Yes❌ No
Resources get public IPs✅ Can❌ Cannot
Direct internet access✅ Yes❌ No (needs NAT)
Typical residentsALB, Bastion hosts, web serversDatabases, caches, app servers

Key insight: What makes a subnet "public" or "private" is only the route table — whether it has a route to the Internet Gateway. Nothing else.

Multi-AZ subnets for high availability

Always create subnets across at least 2 AZs:

VPC (10.0.0.0/16)
├── Public Subnet AZ-a (10.0.1.0/24)
├── Public Subnet AZ-b (10.0.2.0/24)
├── Private Subnet AZ-a (10.0.3.0/24)
└── Private Subnet AZ-b (10.0.4.0/24)

This way, if one AZ goes down, your app keeps running in the other.


🚪 Internet Gateway (IGW)

  • Connects your VPC to the public internet

  • One per VPC (you can only attach one IGW to a VPC)

  • Horizontally scaled, redundant, highly available — AWS manages it

  • Free — no hourly charge or data processing fee

  • Without it, nothing in your VPC can reach (or be reached from) the internet

To make a resource internet-accessible you need ALL of these:

  1. IGW attached to the VPC

  2. Route table entry pointing 0.0.0.0/0 → IGW

  3. Resource has a public IP or Elastic IP

  4. Security group allows the traffic


🔄 NAT Gateway

Allows resources in private subnets to access the internet outbound only (e.g., to download updates, pull Docker images).

Key details:

  • Lives in a public subnet

  • Requires an Elastic IP

  • Costs ~$32/month + $0.045/GB data processed

  • One per AZ for high availability (so 2-3 AZs = $64–96/month just for NAT)

  • Managed by AWS — no patching needed

Alternative to save money: Place resources in public subnets with public IPs instead of using a NAT Gateway. This is less secure but saves ~$100+/month. This is what many dev/staging environments do.


🗺 Route Tables

Every subnet is associated with a route table. The route table tells traffic where to go.

Public subnet route table

Destination        → Target
172.16.0.0/16 → local (stay inside VPC)
0.0.0.0/0 → igw-xxxx (internet gateway)

Private subnet route table (with NAT)

Destination        → Target
172.16.0.0/16 → local (stay inside VPC)
0.0.0.0/0 → nat-xxxx (NAT gateway)

Private subnet route table (no NAT, fully isolated)

Destination        → Target
172.16.0.0/16 → local (stay inside VPC)

The local route is automatic and cannot be removed. It ensures all VPC-internal traffic stays internal.


🛡 Security Groups

The most important security control in AWS. Stateful firewalls attached to individual resources (EC2, RDS, ECS, ALB, etc.).

Key properties

PropertySecurity Group
LevelResource (instance) level
Stateful?✅ Yes — if inbound is allowed, response is auto-allowed
Default behaviorDeny all inbound, allow all outbound
RulesAllow rules only (no deny rules)
Can referenceOther security groups, CIDR blocks, or prefix lists

Security group chaining (best practice)

Instead of using IP addresses, security groups reference other security groups:

Internet → ALB SG (allows port 80/443 from 0.0.0.0/0)


ECS SG (allows port 5000 from ALB SG only)


RDS SG (allows port 5432 from ECS SG only)
Redis SG (allows port 6379 from ECS SG only)

Why this matters: If you add a new ECS task, it automatically gets access to RDS because it has the ECS security group attached. No need to update IP addresses anywhere.

Common port reference

ServicePortProtocol
HTTP80TCP
HTTPS443TCP
SSH22TCP
PostgreSQL5432TCP
MySQL3306TCP
Redis6379TCP
Custom app (e.g., Redash)5000TCP

🧱 Network ACLs (NACLs)

A second layer of security at the subnet level.

PropertyNACLSecurity Group
LevelSubnet levelResource level
Stateful?❌ No — must allow both inbound AND outbound✅ Yes
Default behaviorAllow all (default NACL)Deny all inbound
Rule typeAllow AND deny rulesAllow only
EvaluationRules processed in number orderAll rules evaluated

In practice: Most people leave NACLs at default (allow all) and rely on security groups. NACLs are useful as a backup layer or for blocking specific IP addresses.


🔗 VPC Endpoints

Access AWS services without going through the internet. Traffic stays on AWS's private network.

Two types

TypeCostSupportsHow it works
Gateway EndpointFreeS3, DynamoDB onlyAdds a route to your route table
Interface Endpoint~$7/month + dataMost other AWS services (ECR, Secrets Manager, CloudWatch, etc.)Creates an ENI in your subnet

When to use: If your resources are in a private subnet with no NAT Gateway, VPC Endpoints let them access AWS services like S3 or ECR without internet access.


🔀 VPC Peering & Transit Gateway

VPC Peering

  • Connects two VPCs so they can communicate using private IPs

  • Can peer across regions and across AWS accounts

  • Free (you only pay normal data transfer)

  • CIDR ranges cannot overlap

  • Gets messy with 3+ VPCs (every pair needs its own peering connection)

Transit Gateway

  • A central hub that connects multiple VPCs, VPNs, and on-premises networks

  • Much cleaner than peering when you have many VPCs

  • Costs ~$0.05/hour per attachment + data transfer

  • Best for organizations with 3+ VPCs


🔄 Traffic Flow Example (Redash Setup)

Here's how a user request flows through the VPC to reach Redash:


1. User browser → https://redash.yourdomain.com


2. DNS (Route 53) → resolves to ALB's public IP


3. Internet Gateway → allows traffic into VPC


4. ALB (public subnet) → SG allows 443 from 0.0.0.0/0
│ terminates SSL, forwards to target group


5. Target Group → routes to ECS task on port 5000


6. ECS Task (public subnet) → SG allows 5000 from ALB SG
│ runs Redash containers

├──→ RDS (private subnet) → SG allows 5432 from ECS SG
│ returns query results

└──→ Redis (private subnet) → SG allows 6379 from ECS SG
returns cached data

Why can ECS talk to RDS across different subnets? Because they're in the same VPC. The local route (172.16.0.0/16 → local) keeps all internal VPC traffic internal. Security groups then control which specific resources can communicate.


🏛 Common Architecture Patterns

Pattern 1: Simple (Dev/Staging) — No NAT Gateway

Internet → IGW → Public Subnet (ALB + ECS with public IPs)

Private Subnet (RDS, Redis)

  • Cost: ~$0/month for networking

  • Trade-off: ECS tasks have public IPs (slightly less secure)

Pattern 2: Standard (Production)

Internet → IGW → Public Subnet (ALB only)

Private Subnet (ECS tasks, app servers)
│ │
NAT Gateway VPC Endpoints
│ │
(outbound (AWS services
internet) privately)

Isolated Subnet (RDS, Redis)

  • Cost: ~$32–96/month for NAT

  • Benefit: No public IPs on compute resources

Pattern 3: Enterprise (Multi-VPC)

On-Premises ←→ Transit Gateway ←→ VPC-Prod
│ ←→ VPC-Staging
│ ←→ VPC-Dev
│ ←→ Shared Services VPC

  • Cost: Higher (Transit Gateway + multiple NATs)

  • Benefit: Full isolation between environments


💰 Cost Breakdown

ComponentCostNotes
VPCFree
SubnetsFree
Internet GatewayFree
Route TablesFree
Security GroupsFree
NACLsFree
Elastic IP (attached)FreeCharged if NOT attached (~$3.65/month)
NAT Gateway~$32/month + $0.045/GBPer AZ — multiply by number of AZs
Gateway VPC Endpoint (S3/DynamoDB)Free
Interface VPC Endpoint~$7/month + $0.01/GBPer endpoint, per AZ
VPC PeeringFreeData transfer charges apply
Transit Gateway~$36/month per attachment+ $0.02/GB processed
Data transfer (cross-AZ)$0.01/GB each wayAdds up with high traffic
Data transfer (out to internet)~$0.09/GBFirst 100GB/month may be free

✅ Best Practices Checklist

  • Plan CIDR ranges before creating VPCs — avoid overlap with other VPCs and on-prem

  • Use multiple AZs — minimum 2, ideally 3 for high availability

  • Put databases in private subnets — never expose RDS to the public internet

  • Use security group chaining — reference SGs instead of IP addresses

  • Enable VPC Flow Logs — for debugging and security auditing

  • Enable DNS hostnames + DNS resolution — needed for many AWS services

  • Use S3 Gateway Endpoint — it's free and avoids NAT data charges for S3 traffic

  • Tag everything — VPC, subnets, route tables, security groups

  • Use separate VPCs for production vs dev/staging

  • Use AWS Secrets Manager for database credentials — don't hardcode passwords

  • Set "Publicly Accessible" to false on RDS instances

  • Review security groups regularly — remove unused rules and overly broad access


❌ Common Mistakes & Troubleshooting

"I can't connect to my RDS from my laptop"

Why: RDS is in a private subnet, SG only allows traffic from ECS SG, and "Publicly Accessible" is false.
Fix: Use a bastion host, AWS Session Manager, or VPN to connect. Never make RDS publicly accessible in production.

"My ECS task can't pull Docker images"

Why: Task is in a private subnet with no internet access.
Fix: Either add a NAT Gateway, move to a public subnet with a public IP, or use VPC Endpoints for ECR.

"My security group rule isn't working"

Why: Common causes:

  • Wrong port number

  • Referenced wrong security group

  • Forgot outbound rule on NACL (NACLs are stateless!)

  • Resource doesn't have the SG attached

"My subnets ran out of IPs"

Why: Used too small a CIDR (e.g., /28 = only 11 usable IPs after AWS reserves 5).
Fix: Create a larger subnet. You can add secondary CIDR blocks to a VPC.

"Cross-AZ data transfer costs are high"

Why: Traffic between AZs costs $0.01/GB each direction.
Fix: Co-locate related resources in the same AZ where possible, or accept the cost for HA.


Official AWS Documentation

Learning Resources

Tools


📝 Quick Reference Card

VPC         = Your private network         (Free)
Subnet = A room in your network (Free)
IGW = Front door to internet (Free)
NAT GW = One-way outbound door ($$$)
Route Table = Traffic signs (Free)
Security Group = Bodyguard per resource (Free, stateful)
NACL = Building security gate (Free, stateless)
VPC Endpoint = Internal tunnel to AWS (Free for S3/DynamoDB)

Public subnet = has route to IGW
Private subnet = no route to IGW
That's literally the only difference.


Last updated: March 2026

Related Articles