AWS for DevOps — Networking Exercises

4 minute read

4.6 — Practice Exercises

Test your understanding of VPCs, subnets, route tables, gateways, NACLs, and VPC endpoints.


Exercise 1 — Design a VPC CIDR Plan

Design a CIDR allocation for a VPC that needs public, private, and data subnets across three availability zones. Each subnet should hold at least 200 hosts.

Show Answer

VPC CIDR: 10.0.0.0/16 (65,531 usable IPs)

Subnet CIDR AZ Usable IPs Purpose
public-1a 10.0.1.0/24 ap-south-1a 251 ALB, NAT GW
public-1b 10.0.2.0/24 ap-south-1b 251 ALB, NAT GW
public-1c 10.0.3.0/24 ap-south-1c 251 ALB, NAT GW
private-1a 10.0.10.0/24 ap-south-1a 251 App servers
private-1b 10.0.11.0/24 ap-south-1b 251 App servers
private-1c 10.0.12.0/24 ap-south-1c 251 App servers
data-1a 10.0.20.0/24 ap-south-1a 251 RDS, ElastiCache
data-1b 10.0.21.0/24 ap-south-1b 251 RDS, ElastiCache
data-1c 10.0.22.0/24 ap-south-1c 251 RDS, ElastiCache

Why this works:

  • /24 gives 251 usable IPs per subnet — more than the 200 minimum
  • Three tiers (public, private, data) provide defense in depth
  • Three AZs provide high availability
  • CIDR ranges don’t overlap and leave room for future subnets (10.0.30.0/24, etc.)

Exercise 2 — Build a Public + Private Subnet

Create a VPC, one public subnet, one private subnet, an Internet Gateway, and a NAT Gateway. Set up route tables so the public subnet has internet access and the private subnet can reach the internet through NAT.

Show Answer
# Create VPC
$ aws ec2 create-vpc --cidr-block 10.0.0.0/16 \
    --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=exercise-vpc}]'
# → vpc-ex123

# Enable DNS
$ aws ec2 modify-vpc-attribute --vpc-id vpc-ex123 --enable-dns-hostnames '{"Value":true}'

# Create subnets
$ aws ec2 create-subnet --vpc-id vpc-ex123 --cidr-block 10.0.1.0/24 \
    --availability-zone ap-south-1a \
    --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public}]'
# → subnet-pub

$ aws ec2 create-subnet --vpc-id vpc-ex123 --cidr-block 10.0.10.0/24 \
    --availability-zone ap-south-1a \
    --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private}]'
# → subnet-prv

# Create and attach Internet Gateway
$ aws ec2 create-internet-gateway --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=ex-igw}]'
# → igw-ex123
$ aws ec2 attach-internet-gateway --internet-gateway-id igw-ex123 --vpc-id vpc-ex123

# Public route table
$ aws ec2 create-route-table --vpc-id vpc-ex123
# → rtb-pub
$ aws ec2 create-route --route-table-id rtb-pub --destination-cidr-block 0.0.0.0/0 --gateway-id igw-ex123
$ aws ec2 associate-route-table --route-table-id rtb-pub --subnet-id subnet-pub
$ aws ec2 modify-subnet-attribute --subnet-id subnet-pub --map-public-ip-on-launch

# NAT Gateway
$ aws ec2 allocate-address --domain vpc
# → eipalloc-nat
$ aws ec2 create-nat-gateway --subnet-id subnet-pub --allocation-id eipalloc-nat
# → nat-ex123
$ aws ec2 wait nat-gateway-available --nat-gateway-ids nat-ex123

# Private route table
$ aws ec2 create-route-table --vpc-id vpc-ex123
# → rtb-prv
$ aws ec2 create-route --route-table-id rtb-prv --destination-cidr-block 0.0.0.0/0 --nat-gateway-id nat-ex123
$ aws ec2 associate-route-table --route-table-id rtb-prv --subnet-id subnet-prv

Verification:

  • Instance in public subnet → can reach internet directly
  • Instance in private subnet → can reach internet through NAT, but cannot be reached from internet

Exercise 3 — NACL to Block a Specific IP

Your web server is receiving malicious traffic from 198.51.100.25. Create a NACL rule that blocks this IP while still allowing all other HTTPS traffic.

Show Answer
# Add a DENY rule with a LOW rule number (evaluated before the ALLOW)
$ aws ec2 create-network-acl-entry \
    --network-acl-id acl-pub123 \
    --rule-number 50 \
    --protocol -1 \
    --cidr-block 198.51.100.25/32 \
    --rule-action deny \
    --ingress

# Existing rule 100 allows HTTPS from 0.0.0.0/0 — it stays

How it works:

  • Rule 50 (Deny 198.51.100.25) is evaluated before rule 100 (Allow 0.0.0.0/0)
  • Traffic from the malicious IP hits rule 50 first → DENIED
  • Traffic from all other IPs skips rule 50 → hits rule 100 → ALLOWED

Why not use a security group? Security groups only have Allow rules — you cannot Deny a specific IP. NACLs support Deny rules, making them the right tool for IP blocking.


Exercise 4 — Create an S3 Gateway Endpoint

Create a gateway endpoint for S3 so that EC2 instances in private subnets can access S3 without going through the NAT Gateway.

Show Answer
$ aws ec2 create-vpc-endpoint \
    --vpc-id vpc-0abc123 \
    --service-name com.amazonaws.ap-south-1.s3 \
    --route-table-ids rtb-prv123 rtb-prv456 \
    --tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Name,Value=s3-endpoint}]'
{
    "VpcEndpoint": {
        "VpcEndpointId": "vpce-s3abc",
        "VpcEndpointType": "Gateway",
        "ServiceName": "com.amazonaws.ap-south-1.s3"
    }
}

# Verify the route was added
$ aws ec2 describe-route-tables --route-table-ids rtb-prv123 \
    --query 'RouteTables[0].Routes[?GatewayId==`vpce-s3abc`]'

Benefits:

  • S3 traffic no longer goes through NAT Gateway → no NAT data processing charges
  • Traffic stays on AWS private network → lower latency
  • Gateway endpoints are completely free
  • No changes needed in your application code

Exercise 5 — VPC Peering Design

You have two VPCs: dev-vpc (10.0.0.0/16) and shared-vpc (10.1.0.0/16). The shared VPC hosts an internal Docker registry. Explain how to set up peering so dev instances can pull images from the shared registry.

Show Answer
# Step 1 — Create peering connection
$ aws ec2 create-vpc-peering-connection \
    --vpc-id vpc-dev \
    --peer-vpc-id vpc-shared
# → pcx-ds123

# Step 2 — Accept the peering
$ aws ec2 accept-vpc-peering-connection \
    --vpc-peering-connection-id pcx-ds123

# Step 3 — Add routes in BOTH VPCs
# Dev VPC: route to shared VPC
$ aws ec2 create-route \
    --route-table-id rtb-dev-private \
    --destination-cidr-block 10.1.0.0/16 \
    --vpc-peering-connection-id pcx-ds123

# Shared VPC: route back to dev VPC
$ aws ec2 create-route \
    --route-table-id rtb-shared-private \
    --destination-cidr-block 10.0.0.0/16 \
    --vpc-peering-connection-id pcx-ds123

# Step 4 — Update security groups
# In shared VPC: allow Docker registry port from dev VPC CIDR
$ aws ec2 authorize-security-group-ingress \
    --group-id sg-registry \
    --ip-permissions \
        'IpProtocol=tcp,FromPort=5000,ToPort=5000,IpRanges=[{CidrIp=10.0.0.0/16,Description="From dev VPC"}]'

Checklist:

  1. ✅ CIDRs don’t overlap (10.0.0.0/16 vs 10.1.0.0/16)
  2. ✅ Routes added in both VPCs
  3. ✅ Security groups updated to allow cross-VPC traffic
  4. ✅ DNS resolution enabled for the peering connection (if using private DNS)

Next Chapter → Storage (S3 & EBS)

Updated: