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
- Use /24 subnets (256 IPs) for easy calculation
- Use multiple AZs for high availability
- Keep databases in private subnets
- Use VPC endpoints for AWS services
- Implement least-privilege with security groups
- Use NACLs as a subnet-level firewall
- 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