Skip to main content
AWS VPC Architecture

Module Overview

Estimated Time: 5-6 hours | Difficulty: Intermediate-Advanced | Prerequisites: Core Concepts
This module covers AWS networking from fundamentals to advanced architectures. You’ll learn to design secure, scalable, and highly available network topologies. What You’ll Learn:
  • VPC design and CIDR planning
  • Public and private subnet architectures
  • Security groups and NACLs for defense in depth
  • Load balancers (ALB, NLB) and routing
  • VPC connectivity (Peering, Transit Gateway, VPN)
  • Route 53 DNS and CloudFront CDN
  • Network troubleshooting techniques

VPC (Virtual Private Cloud)

A VPC is your isolated network in AWS. Every resource you launch runs inside a VPC.

VPC Architecture Deep Dive

┌────────────────────────────────────────────────────────────────────────┐
│                      Production VPC (10.0.0.0/16)                       │
│                        65,536 IP addresses                              │
├────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   ┌─────────────────────────────────────────────────────────────────┐  │
│   │                    Availability Zone 1 (us-east-1a)              │  │
│   │                                                                  │  │
│   │  ┌───────────────────────┐  ┌───────────────────────┐           │  │
│   │  │  PUBLIC SUBNET        │  │  PRIVATE SUBNET       │           │  │
│   │  │  10.0.1.0/24          │  │  10.0.10.0/24         │           │  │
│   │  │  (251 usable IPs)     │  │  (251 usable IPs)     │           │  │
│   │  │                       │  │                       │           │  │
│   │  │  ┌─────────────────┐  │  │  ┌─────────────────┐  │           │  │
│   │  │  │   NAT Gateway   │  │  │  │  App Server     │  │           │  │
│   │  │  │   (EIP)         │  │  │  │  (EC2)          │  │           │  │
│   │  │  └─────────────────┘  │  │  └─────────────────┘  │           │  │
│   │  │                       │  │                       │           │  │
│   │  │  ┌─────────────────┐  │  │  ┌─────────────────┐  │           │  │
│   │  │  │   Bastion Host  │  │  │  │   Database      │  │           │  │
│   │  │  │   (optional)    │  │  │  │   (RDS)         │  │           │  │
│   │  │  └─────────────────┘  │  │  └─────────────────┘  │           │  │
│   │  └───────────────────────┘  └───────────────────────┘           │  │
│   │                                                                  │  │
│   │  ┌───────────────────────┐                                      │  │
│   │  │  DATA SUBNET          │  (Optional - for databases only)     │  │
│   │  │  10.0.20.0/24         │                                      │  │
│   │  └───────────────────────┘                                      │  │
│   │                                                                  │  │
│   └─────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│   ┌─────────────────────────────────────────────────────────────────┐  │
│   │                    Availability Zone 2 (us-east-1b)              │  │
│   │                         (Mirror of AZ1)                          │  │
│   │  ┌───────────────────────┐  ┌───────────────────────┐           │  │
│   │  │  PUBLIC: 10.0.2.0/24  │  │  PRIVATE: 10.0.11.0/24│           │  │
│   │  │  NAT Gateway          │  │  App Server (replica) │           │  │
│   │  └───────────────────────┘  └───────────────────────┘           │  │
│   │  ┌───────────────────────┐                                      │  │
│   │  │  DATA: 10.0.21.0/24   │                                      │  │
│   │  └───────────────────────┘                                      │  │
│   └─────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│   ┌─────────────────────────────────────────────────────────────────┐  │
│   │                    Availability Zone 3 (us-east-1c)              │  │
│   │  (Similar structure for higher availability)                     │  │
│   └─────────────────────────────────────────────────────────────────┘  │
│                                                                         │
└────────────────────────────────────────────────────────────────────────┘

CIDR Planning Guide

┌────────────────────────────────────────────────────────────────────────┐
│                      CIDR Planning Best Practices                       │
├────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   CIDR NOTATION QUICK REFERENCE:                                       │
│   ─────────────────────────────                                         │
│   /16 = 65,536 IPs  (10.0.0.0 - 10.0.255.255)   ← VPC size            │
│   /20 = 4,096 IPs   (10.0.0.0 - 10.0.15.255)    ← Large subnet        │
│   /24 = 256 IPs     (10.0.0.0 - 10.0.0.255)     ← Standard subnet     │
│   /28 = 16 IPs      (10.0.0.0 - 10.0.0.15)      ← Small subnet        │
│                                                                         │
│   AWS RESERVES 5 IPs per subnet:                                       │
│   • .0   = Network address                                             │
│   • .1   = VPC router                                                  │
│   • .2   = DNS server                                                  │
│   • .3   = Reserved for future                                         │
│   • .255 = Broadcast (reserved)                                        │
│                                                                         │
│   So /24 (256 IPs) → 251 usable                                        │
│      /28 (16 IPs)  → 11 usable                                         │
│                                                                         │
│   RECOMMENDED VPC CIDR RANGES:                                         │
│   ────────────────────────────                                         │
│   10.0.0.0/8     (Class A - 16M IPs) - Private                        │
│   172.16.0.0/12  (Class B - 1M IPs)  - Private                        │
│   192.168.0.0/16 (Class C - 65K IPs) - Private                        │
│                                                                         │
│   MULTI-ENVIRONMENT EXAMPLE:                                           │
│   ─────────────────────────────                                        │
│   Production:  10.0.0.0/16                                             │
│   Staging:     10.1.0.0/16                                             │
│   Development: 10.2.0.0/16                                             │
│   (No overlap = can peer VPCs later)                                   │
│                                                                         │
└────────────────────────────────────────────────────────────────────────┘

VPC with Terraform

# Complete VPC setup with Terraform
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true
  
  tags = {
    Name        = "production-vpc"
    Environment = "production"
  }
}

# Internet Gateway
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id
  
  tags = {
    Name = "production-igw"
  }
}

# Public Subnets (one per AZ)
resource "aws_subnet" "public" {
  count                   = 3
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.${count.index + 1}.0/24"
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
  
  tags = {
    Name = "public-${data.aws_availability_zones.available.names[count.index]}"
    Tier = "public"
  }
}

# Private Subnets (one per AZ)
resource "aws_subnet" "private" {
  count             = 3
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${count.index + 10}.0/24"
  availability_zone = data.aws_availability_zones.available.names[count.index]
  
  tags = {
    Name = "private-${data.aws_availability_zones.available.names[count.index]}"
    Tier = "private"
  }
}

# NAT Gateway (one per AZ for HA)
resource "aws_eip" "nat" {
  count  = 3
  domain = "vpc"
}

resource "aws_nat_gateway" "main" {
  count         = 3
  allocation_id = aws_eip.nat[count.index].id
  subnet_id     = aws_subnet.public[count.index].id
  
  tags = {
    Name = "nat-${count.index + 1}"
  }
}

# Route Tables
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }
  
  tags = {
    Name = "public-rt"
  }
}

resource "aws_route_table" "private" {
  count  = 3
  vpc_id = aws_vpc.main.id
  
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.main[count.index].id
  }
  
  tags = {
    Name = "private-rt-${count.index + 1}"
  }
}

Subnets

Subnets divide your VPC into smaller networks. Each subnet exists in a single AZ.

Public vs Private Subnets

TypeInternet AccessUse Case
PublicHas route to Internet GatewayWeb servers, bastion hosts
PrivateNo direct internet accessDatabases, app servers
┌─────────────────────────────────────────────────────────────────┐
│                        Internet Access                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│                         ┌───────────┐                            │
│                         │  Internet │                            │
│                         └─────┬─────┘                            │
│                               │                                  │
│                         ┌─────▼─────┐                            │
│                         │  Internet │                            │
│                         │  Gateway  │                            │
│                         └─────┬─────┘                            │
│                               │                                  │
│   ┌───────────────────────────┼───────────────────────────────┐ │
│   │                     VPC   │                                │ │
│   │                           │                                │ │
│   │   ┌───────────────────────▼──────────────────────────┐     │ │
│   │   │              Public Subnet                        │     │ │
│   │   │   Route: 0.0.0.0/0 → Internet Gateway            │     │ │
│   │   │                                                   │     │ │
│   │   │   ┌──────────┐    Public IP                       │     │ │
│   │   │   │   EC2    │◄──────────                         │     │ │
│   │   │   └──────────┘                                    │     │ │
│   │   └──────────────────────────────────────────────────┘     │ │
│   │                           │                                │ │
│   │   ┌───────────────────────▼──────────────────────────┐     │ │
│   │   │              Private Subnet                       │     │ │
│   │   │   Route: 0.0.0.0/0 → NAT Gateway (for outbound)  │     │ │
│   │   │                                                   │     │ │
│   │   │   ┌──────────┐    No public IP                    │     │ │
│   │   │   │   RDS    │                                    │     │ │
│   │   │   └──────────┘                                    │     │ │
│   │   └──────────────────────────────────────────────────┘     │ │
│   │                                                            │ │
│   └────────────────────────────────────────────────────────────┘ │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Gateways

Internet Gateway (IGW)

Allows resources with public IPs to access the internet.

NAT Gateway

Allows private subnet resources to access the internet (outbound only).
┌────────────────────────────────────────────────────────────────┐
│                    NAT Gateway Pattern                          │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│                         Internet                                │
│                            │                                    │
│                    ┌───────▼───────┐                           │
│                    │Internet Gateway│                           │
│                    └───────┬───────┘                           │
│                            │                                    │
│   ┌────────────────────────┼────────────────────────────────┐  │
│   │ Public Subnet          │                                 │  │
│   │                 ┌──────▼──────┐                          │  │
│   │                 │ NAT Gateway │                          │  │
│   │                 │ (with EIP)  │                          │  │
│   │                 └──────┬──────┘                          │  │
│   └────────────────────────┼────────────────────────────────┘  │
│                            │                                    │
│   ┌────────────────────────┼────────────────────────────────┐  │
│   │ Private Subnet         │                                 │  │
│   │                 ┌──────▼──────┐                          │  │
│   │                 │    EC2      │  Can reach internet      │  │
│   │                 │  (private)  │  (for updates, APIs)     │  │
│   │                 └─────────────┘  Cannot be reached       │  │
│   └─────────────────────────────────────────────────────────┘  │
│                                                                 │
└────────────────────────────────────────────────────────────────┘
NAT Gateway costs: ~$0.045/hour + data processing charges. Consider NAT instances for dev environments to save costs.

Security Groups Deep Dive

Virtual firewalls for EC2 instances. Stateful - return traffic is automatically allowed.

Security Group Architecture

┌────────────────────────────────────────────────────────────────────────┐
│                    Defense in Depth with Security Groups                │
├────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Internet                                                              │
│       │                                                                 │
│       ▼                                                                 │
│   ┌─────────────────────────────────────────────────────────────────┐  │
│   │  SG: alb-sg                                                      │  │
│   │  Inbound:  443 from 0.0.0.0/0                                   │  │
│   │  Outbound: All to web-sg                                        │  │
│   │                                                                  │  │
│   │  ┌─────────────────────────────────────────────────────────┐    │  │
│   │  │           Application Load Balancer                      │    │  │
│   │  └─────────────────────────────────────────────────────────┘    │  │
│   └─────────────────────────────────────────────────────────────────┘  │
│                               │                                         │
│                               ▼                                         │
│   ┌─────────────────────────────────────────────────────────────────┐  │
│   │  SG: web-sg                                                      │  │
│   │  Inbound:  8080 from alb-sg (reference SG, not IP!)             │  │
│   │  Inbound:  22 from bastion-sg (SSH)                             │  │
│   │  Outbound: 3306 to db-sg                                        │  │
│   │  Outbound: 6379 to cache-sg                                     │  │
│   │  Outbound: 443 to 0.0.0.0/0 (for external APIs)                 │  │
│   │                                                                  │  │
│   │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │  │
│   │  │   Web EC2    │  │   Web EC2    │  │   Web EC2    │          │  │
│   │  └──────────────┘  └──────────────┘  └──────────────┘          │  │
│   └─────────────────────────────────────────────────────────────────┘  │
│                               │                                         │
│                               ▼                                         │
│   ┌─────────────────────────────────────────────────────────────────┐  │
│   │  SG: db-sg                                                       │  │
│   │  Inbound:  3306 from web-sg ONLY                                │  │
│   │  Outbound: None needed (stateful)                               │  │
│   │                                                                  │  │
│   │  ┌────────────────────────────────────────────────────────────┐ │  │
│   │  │                    RDS MySQL                                │ │  │
│   │  └────────────────────────────────────────────────────────────┘ │  │
│   └─────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│   KEY PRINCIPLES:                                                       │
│   ✅ Reference security groups, not IP addresses                       │
│   ✅ Principle of least privilege                                       │
│   ✅ Separate SG per tier (web, app, db)                               │
│   ✅ Never open 0.0.0.0/0 except for ALB inbound                       │
│                                                                         │
└────────────────────────────────────────────────────────────────────────┘

Security Group with Terraform

# ALB Security Group
resource "aws_security_group" "alb" {
  name        = "alb-sg"
  description = "Security group for Application Load Balancer"
  vpc_id      = aws_vpc.main.id

  ingress {
    description = "HTTPS from anywhere"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "HTTP for redirect"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    description     = "To web servers"
    from_port       = 8080
    to_port         = 8080
    protocol        = "tcp"
    security_groups = [aws_security_group.web.id]
  }

  tags = {
    Name = "alb-sg"
  }
}

# Web Server Security Group
resource "aws_security_group" "web" {
  name        = "web-sg"
  description = "Security group for web servers"
  vpc_id      = aws_vpc.main.id

  ingress {
    description     = "From ALB"
    from_port       = 8080
    to_port         = 8080
    protocol        = "tcp"
    security_groups = [aws_security_group.alb.id]
  }

  egress {
    description     = "To database"
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.db.id]
  }

  egress {
    description = "HTTPS for external APIs"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "web-sg"
  }
}

# Database Security Group
resource "aws_security_group" "db" {
  name        = "db-sg"
  description = "Security group for RDS"
  vpc_id      = aws_vpc.main.id

  ingress {
    description     = "MySQL from web servers"
    from_port       = 3306
    to_port         = 3306
    protocol        = "tcp"
    security_groups = [aws_security_group.web.id]
  }

  # No egress needed - stateful
  
  tags = {
    Name = "db-sg"
  }
}

Security Groups vs NACLs

┌────────────────────────────────────────────────────────────────────────┐
│                    Security Groups vs NACLs                             │
├────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│   Feature            │ Security Group      │ NACL                      │
│   ───────────────────┼─────────────────────┼─────────────────────────  │
│   Level              │ Instance (ENI)      │ Subnet                    │
│   State              │ Stateful            │ Stateless                 │
│   Rules              │ Allow only          │ Allow AND Deny            │
│   Evaluation         │ All rules checked   │ Rules in order (by #)     │
│   Default            │ Deny all in         │ Allow all                 │
│   Applies to         │ Instances you assign│ All instances in subnet   │
│   Return traffic     │ Automatic           │ Must explicitly allow     │
│                                                                         │
│   WHEN TO USE EACH:                                                    │
│   ─────────────────                                                    │
│   Security Groups: Primary defense, fine-grained instance control      │
│   NACLs: Subnet-level blocking, deny specific IPs, compliance         │
│                                                                         │
│   NACL EXAMPLE - Block specific IP:                                    │
│   ┌────────────────────────────────────────────────────────────────┐  │
│   │ Rule # │ Type   │ Protocol │ Port │ Source      │ Allow/Deny  │  │
│   │────────┼────────┼──────────┼──────┼─────────────┼─────────────│  │
│   │ 50     │ Custom │ TCP      │ ALL  │ 1.2.3.4/32  │ DENY        │  │
│   │ 100    │ HTTPS  │ TCP      │ 443  │ 0.0.0.0/0   │ ALLOW       │  │
│   │ 110    │ HTTP   │ TCP      │ 80   │ 0.0.0.0/0   │ ALLOW       │  │
│   │ *      │ ALL    │ ALL      │ ALL  │ 0.0.0.0/0   │ DENY        │  │
│   └────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│   ⚠️ Don't forget outbound rules for NACLs! (ephemeral ports 1024-65535)│
│                                                                         │
└────────────────────────────────────────────────────────────────────────┘

Load Balancing

Distribute traffic across multiple targets.
AWS Load Balancer Types Comparison

Load Balancer Types

TypeLayerUse Case
ALB (Application)Layer 7 (HTTP/HTTPS)Web apps, microservices
NLB (Network)Layer 4 (TCP/UDP)Gaming, IoT, low latency
GLB (Gateway)Layer 3Firewalls, IDS/IPS
CLB (Classic)Layer 4/7Legacy (avoid)

Application Load Balancer (ALB)

┌────────────────────────────────────────────────────────────────┐
│                    ALB Architecture                             │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Client Request                                                │
│        │                                                        │
│        ▼                                                        │
│   ┌─────────────────────────────────────────────────────────┐  │
│   │              Application Load Balancer                   │  │
│   │                                                          │  │
│   │   Listener (Port 443)                                    │  │
│   │        │                                                 │  │
│   │        ▼                                                 │  │
│   │   ┌─────────────────────────────────────────────────┐   │  │
│   │   │              Routing Rules                       │   │  │
│   │   │                                                  │   │  │
│   │   │  /api/*    → Target Group: API Servers          │   │  │
│   │   │  /static/* → Target Group: Static (S3)          │   │  │
│   │   │  /*        → Target Group: Web Servers          │   │  │
│   │   │                                                  │   │  │
│   │   └─────────────────────────────────────────────────┘   │  │
│   └─────────────────────────────────────────────────────────┘  │
│                     │              │              │             │
│              ┌──────┴───┐   ┌──────┴───┐   ┌──────┴───┐        │
│              │ Target   │   │ Target   │   │ Target   │        │
│              │ Group 1  │   │ Group 2  │   │ Group 3  │        │
│              └──────────┘   └──────────┘   └──────────┘        │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

ALB Features

  • Path-based routing: /api/* → API servers
  • Host-based routing: api.example.com → API, www.example.com → Web
  • SSL termination: HTTPS offloading
  • Health checks: Automatic target monitoring
  • Sticky sessions: Cookie-based affinity

Route 53

AWS DNS service with health checking and traffic routing.

Routing Policies

PolicyUse Case
SimpleSingle resource
WeightedA/B testing, gradual rollouts
LatencyRoute to lowest latency region
FailoverActive-passive DR
GeolocationRoute by user location
GeoproximityRoute by geographic distance
Multi-valueReturn multiple healthy IPs
┌────────────────────────────────────────────────────────────────┐
│                  Route 53 Failover Routing                      │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│   DNS Query: api.example.com                                    │
│                   │                                             │
│                   ▼                                             │
│           ┌──────────────┐                                      │
│           │   Route 53   │                                      │
│           │ Health Check │                                      │
│           └──────┬───────┘                                      │
│                  │                                              │
│         ┌────────┴────────┐                                     │
│         │                 │                                     │
│         ▼                 ▼                                     │
│   ┌───────────┐    ┌───────────┐                               │
│   │  Primary  │    │ Secondary │                               │
│   │ us-east-1 │    │ us-west-2 │                               │
│   │  (active) │    │ (standby) │                               │
│   └───────────┘    └───────────┘                               │
│                                                                 │
│   If primary fails health check → Route to secondary            │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

CloudFront (CDN)

Content Delivery Network for low-latency content delivery.
┌────────────────────────────────────────────────────────────────┐
│                    CloudFront Distribution                      │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│   User (Europe)                  User (Asia)                    │
│        │                              │                         │
│        ▼                              ▼                         │
│   ┌─────────────┐              ┌─────────────┐                 │
│   │ Edge (EU)   │              │ Edge (Asia) │                 │
│   │ Paris       │              │ Tokyo       │                 │
│   └──────┬──────┘              └──────┬──────┘                 │
│          │                            │                         │
│          │      Cache Miss?           │                         │
│          └──────────┬─────────────────┘                         │
│                     │                                           │
│                     ▼                                           │
│             ┌──────────────┐                                    │
│             │   Origin     │                                    │
│             │ (S3 or ALB)  │                                    │
│             │  us-east-1   │                                    │
│             └──────────────┘                                    │
│                                                                 │
│   Benefits:                                                     │
│   • Low latency (edge caching)                                  │
│   • DDoS protection                                             │
│   • SSL/TLS termination                                         │
│   • Origin protection                                           │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

VPC Peering & Transit Gateway

Connect VPCs together.

VPC Peering

┌─────────────────┐         ┌─────────────────┐
│   VPC A         │         │   VPC B         │
│ 10.0.0.0/16     │◄───────►│ 10.1.0.0/16     │
│                 │ Peering │                 │
└─────────────────┘         └─────────────────┘

• 1-to-1 connection
• Non-transitive (A↔B, B↔C doesn't mean A↔C)
• Cross-region supported

Transit Gateway

                    ┌─────────────────┐
                    │ Transit Gateway │
                    └────────┬────────┘
               ┌─────────────┼─────────────┐
               │             │             │
        ┌──────▼──────┐ ┌────▼────┐ ┌──────▼──────┐
        │   VPC A     │ │  VPC B  │ │   VPC C     │
        │ 10.0.0.0/16 │ │10.1.0.0 │ │ 10.2.0.0/16 │
        └─────────────┘ └─────────┘ └─────────────┘

• Hub-and-spoke model
• Transitive routing
• Connect VPCs, VPNs, Direct Connect

🎯 Interview Questions

Architecture:
  1. VPC: 10.0.0.0/16 (65,536 IPs)
  2. Subnets (across 3 AZs):
    • Public: 10.0.1.0/24, 10.0.2.0/24, 10.0.3.0/24
    • Private (App): 10.0.10.0/24, 10.0.11.0/24, 10.0.12.0/24
    • Private (DB): 10.0.20.0/24, 10.0.21.0/24, 10.0.22.0/24
  3. Components:
    • ALB in public subnets
    • NAT Gateway per AZ (for HA)
    • App servers in private subnets
    • RDS Multi-AZ in DB subnets
  4. Security:
    • alb-sg: 443 from 0.0.0.0/0
    • web-sg: 8080 from alb-sg
    • db-sg: 3306 from web-sg
  5. Routing:
    • Public: 0.0.0.0/0 → IGW
    • Private: 0.0.0.0/0 → NAT Gateway
Security Groups:
  • Operate at instance level
  • Stateful (return traffic auto-allowed)
  • Allow rules only
  • All rules evaluated
  • Primary security layer
NACLs:
  • Operate at subnet level
  • Stateless (must allow return traffic)
  • Allow AND Deny rules
  • Rules evaluated in order
  • Secondary layer for compliance
Best Practice: Use both for defense in depth. Security groups for fine-grained control, NACLs for subnet-level blocking.
Use ALB when:
  • HTTP/HTTPS traffic
  • Need path-based routing (/api, /static)
  • Need host-based routing (api.example.com)
  • WebSocket support
  • Container-based apps with dynamic ports
Use NLB when:
  • TCP/UDP traffic
  • Need ultra-low latency (<100ms)
  • Need static IP/Elastic IP
  • Gaming, IoT, financial apps
  • Need to preserve source IP
Cost Note: NLB is cheaper at high throughput
Systematic approach:
  1. Security Groups: Check inbound/outbound rules
    aws ec2 describe-security-groups --group-ids sg-xxx
    
  2. NACLs: Check subnet NACL rules (inbound AND outbound)
  3. Route Tables: Verify route to destination exists
    aws ec2 describe-route-tables --filters "Name=vpc-id,Values=vpc-xxx"
    
  4. Internet Gateway: For public access, ensure IGW attached
  5. NAT Gateway: For private subnet outbound, check NAT
  6. VPC Flow Logs: Enable to see accepted/rejected traffic
  7. Instance level: Check OS firewall (iptables, Windows Firewall)
Options:
  1. VPC Peering:
    • 1-to-1 connection
    • Non-transitive
    • Good for fewer than 10 VPCs
    • No single point of failure
  2. Transit Gateway:
    • Hub-and-spoke model
    • Transitive routing
    • Scales to 5,000+ VPCs
    • Centralized management
    • ~0.05/GB+0.05/GB + 0.05/attachment/hour
  3. PrivateLink:
    • Expose service to other VPCs
    • One-way access
    • No IP overlap concerns
Recommendation:
  • Fewer than 5 VPCs: VPC Peering
  • 5+ VPCs: Transit Gateway

🧪 Hands-On Lab: Build a Secure 3-Tier VPC

Objective: Create a production-ready VPC with proper network segmentation
1

Create VPC with CIDR 10.0.0.0/16

Enable DNS hostnames and DNS support
2

Create Subnets

3 public (10.0.1-3.0/24), 3 private app (10.0.10-12.0/24), 3 private DB (10.0.20-22.0/24)
3

Create Internet Gateway

Attach to VPC, create public route table with 0.0.0.0/0 → IGW
4

Create NAT Gateways

One per AZ in public subnets, create private route tables
5

Create Security Groups

alb-sg, web-sg, db-sg with proper chaining
6

Deploy ALB + EC2 + RDS

Test connectivity between tiers
7

Enable VPC Flow Logs

Send to CloudWatch Logs for network monitoring

Networking Best Practices Summary

Key Takeaways:
  1. Always use at least 2 AZs for high availability
  2. Place only load balancers in public subnets
  3. Use security group chaining (reference SGs, not IPs)
  4. Plan CIDR blocks to avoid overlap for future peering
  5. Use NAT Gateway per AZ for HA
  6. Enable VPC Flow Logs for troubleshooting
  7. Use Transit Gateway for 5+ VPCs

Next Module

Security

Master IAM, KMS, encryption, and security best practices