Skip to content
intermediate Phase 2 · AWS Networking

VPC & Subnets

Design virtual private clouds with public/private subnets and routing.

1h 30m
0 problems
Topic Progress 0%

VPC Fundamentals

VPC Fundamentals

A Virtual Private Cloud (VPC) is a logically isolated section of the AWS cloud where you launch resources in a virtual network you define.

VPC Components

Component Description
VPC Isolated virtual network (CIDR block 16-28 bits)
Subnet IP address range within a VPC
Route Table Rules for directing network traffic
Internet Gateway (IGW) Connects VPC to the internet
NAT Gateway Allows outbound internet for private subnets
Elastic IP Static public IP address

Create a VPC

# Create a VPC with a /16 CIDR block
aws ec2 create-vpc --cidr-block 10.0.0.0/16

# Tag the VPC
aws ec2 create-tags --resources vpc-xxx --tags Key=Name,Value=MyVPC

# Enable DNS hostnames
aws ec2 modify-vpc-attribute --vpc-id vpc-xxx --enable-dns-hostnames

# Create subnets
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.1.0/24 --availability-zone us-east-1a
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.2.0/24 --availability-zone us-east-1b
aws ec2 create-subnet --vpc-id vpc-xxx --cidr-block 10.0.3.0/24 --availability-zone us-east-1c

# Create an Internet Gateway
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway --internet-gateway-id igw-xxx --vpc-id vpc-xxx

# Create a route table
aws ec2 create-route-table --vpc-id vpc-xxx
aws ec2 create-route --route-table-id rtb-xxx --destination-cidr-block 0.0.0.0/0 --gateway-id igw-xxx

VPC Architecture

┌─────────────────────────────────────────────────────────────┐
│                        VPC 10.0.0.0/16                      │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐│
│  │  Public Subnet  │  │  Public Subnet  │  │   Private   ││
│  │  10.0.1.0/24    │  │  10.0.2.0/24    │  │   Subnet    ││
│  │  (AZ-1a)        │  │  (AZ-1b)        │  │ 10.0.3.0/24 ││
│  │  ┌──────┐       │  │  ┌──────┐       │  │  (AZ-1c)    ││
│  │  │ EC2  │       │  │  │ EC2  │       │  │  ┌──────┐   ││
│  │  └──────┘       │  │  └──────┘       │  │  │ RDS  │   ││
│  └────────┬────────┘  └────────┬────────┘  │  └──────┘   ││
│           │                    │           └──────┬──────┘│
│  ┌────────▼────────────────────▼────────┐         │       │
│  │         Internet Gateway (IGW)       │    ┌────▼─────┐│
│  └──────────────────┬───────────────────┘    │NAT GW    ││
│                     │                        └────┬─────┘│
│              ┌──────▼──────┐                      │       │
│              │   Internet  │                      │       │
│              └─────────────┘                      │       │
└───────────────────────────────────────────────────┘───────┘

Subnets and Route Tables

Subnets and Route Tables

Public vs Private Subnets

  • Public Subnet: Has a route to an Internet Gateway
  • Private Subnet: No direct route to the internet (only through NAT)
# Associate public subnet with route table
aws ec2 associate-route-table --route-table-id rtb-xxx --subnet-id subnet-public

# Create a private route table
aws ec2 create-route-table --vpc-id vpc-xxx
aws ec2 create-route \
  --route-table-id rtb-private \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id natw-xxx

aws ec2 associate-route-table --route-table-id rtb-private --subnet-id subnet-private

Route Table Rules

┌────────────────────────┬─────────────┬──────────────────┐
│ Destination            │ Target      │ Description      │
├────────────────────────┼─────────────┼──────────────────┤
│ 10.0.0.0/16           │ local       │ VPC internal     │
│ 0.0.0.0/0            │ igw-xxx     │ Internet access  │
│ 172.16.0.0/12        │ pcx-xxx     │ Peering connection│
└────────────────────────┴─────────────┴──────────────────┘

Subnet Sizing Strategy

# Calculate subnets for a /16 VPC
# /24 = 256 IPs per subnet
# Usable IPs = 256 - 5 (AWS reserves 5)

# Create subnets using a script
for i in {1..6}; do
  AZ=$(echo us-east-1{a,b,c,d,e,f} | awk "{print \$$(($i))}")
  CIDR="10.0.$i.0/24"
  aws ec2 create-subnet \
    --vpc-id vpc-xxx \
    --cidr-block $CIDR \
    --availability-zone $AZ \
    --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=Subnet-$AZ}]"
done

NACLs and Security Groups

Network ACLs and Security Groups

NACLs vs Security Groups

Feature Security Groups NACLs
Level Instance level Subnet level
State Stateful Stateless
Rules Allow only Allow and Deny
Evaluation All rules evaluated Rules in order
Default Allow all inbound/outbound Allow all inbound/outbound

NACL Configuration

# Create a NACL
aws ec2 create-network-acl --vpc-id vpc-xxx

# Add rules
aws ec2 create-network-acl-entry \
  --network-acl-id acl-xxx \
  --rule-number 100 \
  --protocol tcp \
  --rule-action allow \
  --cidr-block 0.0.0.0/0 \
  --port-range From=80,To=80

# Deny all traffic
aws ec2 create-network-acl-entry \
  --network-acl-id acl-xxx \
  --rule-number 32767 \
  --protocol -1 \
  --rule-action deny \
  --cidr-block 0.0.0.0/0

# Associate NACL with subnet
aws ec2 associate-network-acl --network-acl-id acl-xxx --subnet-id subnet-xxx

Security Group Best Practices

# Reference another security group (not CIDR)
aws ec2 authorize-security-group-ingress \
  --group-id sg-web \
  --protocol tcp \
  --port 80 \
  --source-group sg-app

# Use prefix lists for known CIDR ranges
aws ec2 create-prefix-list \
  --prefix-list-name "Corporate CIDRs" \
  --max-entries 10 \
  --entries [{"Cidr":"10.0.0.0/8","Description":"Corporate"}]

NAT Gateways and VPC Endpoints

NAT Gateways and VPC Endpoints

NAT Gateway

Allows instances in private subnets to connect to the internet.

# Allocate an Elastic IP
aws ec2 allocate-address --domain vpc

# Create a NAT Gateway in a public subnet
aws ec2 create-nat-gateway \
  --subnet-id subnet-public \
  --allocation-id eipalloc-xxx

# Update private route table
aws ec2 create-route \
  --route-table-id rtb-private \
  --destination-cidr-block 0.0.0.0/0 \
  --nat-gateway-id natw-xxx

VPC Endpoints

Keep traffic within AWS network instead of going over the internet.

# Create a Gateway Endpoint for S3
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxx \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-xxx

# Create an Interface Endpoint for DynamoDB
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxx \
  --service-name com.amazonaws.us-east-1.dynamodb \
  --vpc-endpoint-type Interface \
  --subnet-ids subnet-xxx \
  --security-group-ids sg-endpoint

# List endpoints
aws ec2 describe-vpc-endpoints --filters Name=vpc-id,Values=vpc-xxx

VPC Endpoint Policies

{
  "Statement": [{
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:*",
    "Resource": [
      "arn:aws:s3:::my-bucket",
      "arn:aws:s3:::my-bucket/*"
    ]
  }]
}

VPC Peering and Transit Gateway

VPC Peering and Transit Gateway

VPC Peering

Connect two VPCs privately. Non-overlapping CIDR blocks required.

# Create a peering request
aws ec2 create-vpc-peering-connection \
  --vpc-id vpc-111111 \
  --peer-vpc-id vpc-222222 \
  --peer-owner-id 123456789012

# Accept the peering request
aws ec2 accept-vpc-peering-connection --vpc-peering-connection-id pcx-xxx

# Add route in VPC 1
aws ec2 create-route \
  --route-table-id rtb-vpc1 \
  --destination-cidr-block 10.1.0.0/16 \
  --vpc-peering-connection-id pcx-xxx

# Add route in VPC 2
aws ec2 create-route \
  --route-table-id rtb-vpc2 \
  --destination-cidr-block 10.0.0.0/16 \
  --vpc-peering-connection-id pcx-xxx

Peering Limitations

  • Non-overlapping CIDR blocks
  • No transitive peering (A-B, B-C doesn't mean A-C)
  • Maximum 50 peering connections per VPC
  • Cross-account peering supported

Transit Gateway

Central hub for connecting multiple VPCs and on-premises networks.

# Create Transit Gateway
aws ec2 create-transit-gateway --description "Main TGW"

# Attach VPC to Transit Gateway
aws ec2 create-transit-gateway-vpc-attachment \
  --transit-gateway-id tgw-xxx \
  --vpc-id vpc-xxx \
  --subnet-ids subnet-xxx

# Create route
aws ec2 create-transit-gateway-route \
  --transit-gateway-route-table-id tgw-rtb-xxx \
  --destination-cidr-block 10.1.0.0/16 \
  --transit-gateway-attachment-id tgw-att-xxx

VPC Design Patterns and Best Practices

VPC Design Patterns and Best Practices

Multi-Tier Architecture

┌──────────────────────────────────────────────────────────────┐
│                         VPC                                  │
│  ┌────────────────────────────────────────────────────────┐ │
│  │                Public Tier (Web)                       │ │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐           │ │
│  │  │ ALB-AZ1  │  │ ALB-AZ2  │  │ ALB-AZ3  │           │ │
│  │  └──────────┘  └──────────┘  └──────────┘           │ │
│  └────────────────────┬──────────────────────────────────┘ │
│                       │                                    │
│  ┌────────────────────▼──────────────────────────────────┐ │
│  │              Private Tier (Application)               │ │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────┐           │ │
│  │  │ ECS-AZ1  │  │ ECS-AZ2  │  │ ECS-AZ3  │           │ │
│  │  └──────────┘  └──────────┘  └──────────┘           │ │
│  └────────────────────┬──────────────────────────────────┘ │
│                       │                                    │
│  ┌────────────────────▼──────────────────────────────────┐ │
│  │              Data Tier (Database)                     │ │
│  │  ┌──────────┐  ┌──────────┐                          │ │
│  │  │ RDS-1    │  │ RDS-2    │                          │ │
│  │  └──────────┘  └──────────┘                          │ │
│  └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘

Best Practices

  1. Use /24 subnets (256 IPs) for easy calculation
  2. Use multiple AZs for high availability
  3. Keep databases in private subnets
  4. Use VPC endpoints for AWS services
  5. Implement least-privilege with security groups
  6. Use NACLs as a subnet-level firewall
  7. Enable VPC Flow Logs for debugging
# Enable VPC Flow Logs
aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-xxx \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /vpc/flowlogs