Overview
This tutorial provides a comprehensive exploration of Amazon VPC (Virtual Private Cloud) networking fundamentals, focusing on three critical components: subnets, route tables, and security groups. These concepts form the foundation of secure, scalable AWS infrastructure and appear frequently on the AWS Solutions Architect Associate (SAA-C03) exam.
What This Tutorial Covers:
- Creating and managing VPC subnets (public and private)
- Configuring route tables and understanding routing logic
- Designing and implementing security groups effectively
- Network ACLs vs Security Groups comparison
- Real-world architectural patterns and best practices
Prerequisites:
- AWS account with appropriate IAM permissions (EC2, VPC, CloudWatch)
- AWS CLI v2 installed and configured
- Basic understanding of TCP/IP networking
- Familiarity with AWS Management Console
Why This Matters for SAA-C03: Security and networking design account for approximately 25% of the exam. Understanding VPC architecture, especially subnet segmentation and traffic control, is essential for designing highly available and secure solutions.
Getting Started
First, verify your AWS CLI installation and configure credentials:
aws --version
aws configure
# Enter your Access Key ID, Secret Access Key, default region, and output formatSet environment variables for easier command execution:
export AWS_REGION='us-east-1'
export VPC_CIDR='10.0.0.0/16'
export PROJECT_NAME='cloudninjas-vpc-demo'Create a VPC with our CIDR block:
VPC_ID=$(aws ec2 create-vpc
--cidr-block $VPC_CIDR
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value='$PROJECT_NAME'}]'
--region $AWS_REGION
--query 'Vpc.VpcId'
--output text)
echo 'VPC created with ID: '$VPC_IDEnable DNS hostnames (required for many AWS services):
aws ec2 modify-vpc-attribute
--vpc-id $VPC_ID
--enable-dns-hostnames
--region $AWS_REGIONSubnets: Segmenting Your Network
Subnets are subdivisions of your VPC CIDR block that reside within specific Availability Zones (AZs). Each subnet can be designated as either public (routable to the internet) or private (isolated from direct internet access).
Creating Public Subnets:
# Public Subnet 1 (AZ us-east-1a)
PUBLIC_SUBNET_1=$(aws ec2 create-subnet
--vpc-id $VPC_ID
--cidr-block '10.0.1.0/24'
--availability-zone 'us-east-1a'
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1a}]'
--region $AWS_REGION
--query 'Subnet.SubnetId'
--output text)
# Public Subnet 2 (AZ us-east-1b)
PUBLIC_SUBNET_2=$(aws ec2 create-subnet
--vpc-id $VPC_ID
--cidr-block '10.0.2.0/24'
--availability-zone 'us-east-1b'
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1b}]'
--region $AWS_REGION
--query 'Subnet.SubnetId'
--output text)
echo 'Public Subnet 1: '$PUBLIC_SUBNET_1
echo 'Public Subnet 2: '$PUBLIC_SUBNET_2Creating Private Subnets:
# Private Subnet 1 (AZ us-east-1a)
PRIVATE_SUBNET_1=$(aws ec2 create-subnet
--vpc-id $VPC_ID
--cidr-block '10.0.10.0/24'
--availability-zone 'us-east-1a'
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1a}]'
--region $AWS_REGION
--query 'Subnet.SubnetId'
--output text)
# Private Subnet 2 (AZ us-east-1b)
PRIVATE_SUBNET_2=$(aws ec2 create-subnet
--vpc-id $VPC_ID
--cidr-block '10.0.11.0/24'
--availability-zone 'us-east-1b'
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1b}]'
--region $AWS_REGION
--query 'Subnet.SubnetId'
--output text)
echo 'Private Subnet 1: '$PRIVATE_SUBNET_1
echo 'Private Subnet 2: '$PRIVATE_SUBNET_2Common Pitfalls:
- CIDR Overlap: Ensure subnet CIDR blocks don't overlap and fit within VPC CIDR
- Subnet Size: AWS reserves 5 IP addresses per subnet (network, broadcast, router, DNS, and AWS reserved)
- AZ Distribution: Always spread subnets across multiple AZs for high availability
Verify your subnets:
aws ec2 describe-subnets
--filters 'Name=vpc-id,Values='$VPC_ID
--region $AWS_REGION
--query 'Subnets[*].[SubnetId,CidrBlock,AvailabilityZone]'
--output tableRoute Tables: Controlling Traffic Flow
Route tables are sets of rules (called routes) that determine where network traffic from your subnet or gateway is directed. Each route specifies a destination CIDR block and a target.
Create an Internet Gateway for public access:
IGW_ID=$(aws ec2 create-internet-gateway
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value='$PROJECT_NAME'-igw}]'
--region $AWS_REGION
--query 'InternetGateway.InternetGatewayId'
--output text)
# Attach IGW to VPC
aws ec2 attach-internet-gateway
--vpc-id $VPC_ID
--internet-gateway-id $IGW_ID
--region $AWS_REGION
echo 'Internet Gateway created: '$IGW_IDCreate and configure a public route table:
# Create public route table
PUBLIC_RT=$(aws ec2 create-route-table
--vpc-id $VPC_ID
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]'
--region $AWS_REGION
--query 'RouteTable.RouteTableId'
--output text)
# Add route to Internet Gateway (all traffic 0.0.0.0/0 goes to IGW)
aws ec2 create-route
--route-table-id $PUBLIC_RT
--destination-cidr-block '0.0.0.0/0'
--gateway-id $IGW_ID
--region $AWS_REGION
# Associate public subnets with public route table
aws ec2 associate-route-table
--subnet-id $PUBLIC_SUBNET_1
--route-table-id $PUBLIC_RT
--region $AWS_REGION
aws ec2 associate-route-table
--subnet-id $PUBLIC_SUBNET_2
--route-table-id $PUBLIC_RT
--region $AWS_REGION
echo 'Public route table created and configured: '$PUBLIC_RTCreate a private route table:
# Create private route table
PRIVATE_RT=$(aws ec2 create-route-table
--vpc-id $VPC_ID
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=private-rt}]'
--region $AWS_REGION
--query 'RouteTable.RouteTableId'
--output text)
# Associate private subnets with private route table
aws ec2 associate-route-table
--subnet-id $PRIVATE_SUBNET_1
--route-table-id $PRIVATE_RT
--region $AWS_REGION
aws ec2 associate-route-table
--subnet-id $PRIVATE_SUBNET_2
--route-table-id $PRIVATE_RT
--region $AWS_REGION
echo 'Private route table created: '$PRIVATE_RTView route table configurations:
aws ec2 describe-route-tables
--filters 'Name=vpc-id,Values='$VPC_ID
--region $AWS_REGION
--query 'RouteTables[*].[RouteTableId,Tags[0].Value,Routes[*].[DestinationCidrBlock,GatewayId]]'
--output tableSecurity Groups: Stateful Firewall Rules
Security groups act as virtual firewalls controlling inbound and outbound traffic at the instance level. They are stateful, meaning if outbound traffic is allowed, return traffic is automatically allowed.
Create a web server security group:
WEB_SG=$(aws ec2 create-security-group
--group-name 'web-servers'
--description 'Security group for web servers allowing HTTP/HTTPS'
--vpc-id $VPC_ID
--region $AWS_REGION
--query 'GroupId'
--output text)
echo 'Web Security Group created: '$WEB_SGAdd inbound rules to allow HTTP and HTTPS from anywhere:
# Allow HTTP (port 80)
aws ec2 authorize-security-group-ingress
--group-id $WEB_SG
--protocol tcp
--port 80
--cidr '0.0.0.0/0'
--region $AWS_REGION
# Allow HTTPS (port 443)
aws ec2 authorize-security-group-ingress
--group-id $WEB_SG
--protocol tcp
--port 443
--cidr '0.0.0.0/0'
--region $AWS_REGION
# Allow SSH from specific IP (replace with your IP)
aws ec2 authorize-security-group-ingress
--group-id $WEB_SG
--protocol tcp
--port 22
--cidr '203.0.113.0/24'
--region $AWS_REGIONCreate an application tier security group:
APP_SG=$(aws ec2 create-security-group
--group-name 'app-servers'
--description 'Security group for application servers'
--vpc-id $VPC_ID
--region $AWS_REGION
--query 'GroupId'
--output text)
# Allow traffic only from web security group on port 8080
aws ec2 authorize-security-group-ingress
--group-id $APP_SG
--protocol tcp
--port 8080
--source-group $WEB_SG
--region $AWS_REGION
echo 'Application Security Group created: '$APP_SGView security group rules:
aws ec2 describe-security-groups
--group-ids $WEB_SG $APP_SG
--region $AWS_REGION
--query 'SecurityGroups[*].[GroupId,GroupName,IpPermissions]'
--output textBest Practices:
- Principle of Least Privilege: Only open ports and protocols required
- Use Security Group References: Reference other SGs instead of CIDR blocks for internal communication
- Avoid 0.0.0.0/0 for SSH: Restrict SSH access to known IP ranges
- Regular Audits: Periodically review rules for unnecessary permissions
Exam Tips for AWS Solutions Architect Associate (SAA-C03)
Key Concepts to Master:
- Public vs Private Subnets: Public subnets have routes to IGW; private subnets typically use NAT Gateway for outbound internet access
- Route Table Hierarchy: Most specific route wins; longest prefix match
- Security Groups vs NACLs: SGs are stateful and instance-level; NACLs are stateless and subnet-level
- Availability Zones: Subnets are AZ-specific; always design for multi-AZ redundancy
Common Exam Scenarios:
- High Availability Design: Questions often ask you to design an architecture spanning multiple AZs with redundant subnets
- Security Posture: Expect questions about restricting traffic patterns and implementing defense-in-depth
- Troubleshooting: 'Why can't my EC2 instance reach the internet?' typically involves route table issues
- Migration Scenarios: Moving applications requiring VPC redesign with minimal downtime
Quick Reference Commands:
# List all subnets in a VPC
aws ec2 describe-subnets --filters 'Name=vpc-id,Values=vpc-xxxxx'
# Modify route table (add NAT Gateway route for private subnets)
aws ec2 create-route --route-table-id rtb-xxxxx
--destination-cidr-block '0.0.0.0/0'
--nat-gateway-id nat-xxxxx
# Revoke security group rule
aws ec2 revoke-security-group-ingress --group-id sg-xxxxx
--protocol tcp --port 22 --cidr '0.0.0.0/0'Summary
Key Takeaways:
- VPCs provide isolated network environments; subnets further segment networks within AZs
- Route tables determine traffic direction; always ensure connectivity paths exist for required communication
- Security groups provide instance-level protection using stateful rules based on least privilege principle
- Multi-AZ subnet distribution ensures high availability and disaster recovery capabilities
- Proper VPC design directly impacts security posture, scalability, and compliance requirements
Next Steps:
- Explore NAT Gateways for private subnet internet connectivity
- Implement VPC Flow Logs for traffic analysis and troubleshooting
- Study VPC Peering and Transit Gateways for multi-VPC architectures
- Review AWS Well-Architected Framework networking pillar
- Practice with CloudFormation to automate VPC deployments
For comprehensive SAA-C03 preparation, consult the CloudNinjas.ca AWS Solutions Architect Associate Complete Guide and continue practicing with hands-on labs to internalize these networking patterns.

