Audit Your VPC: Find Accidentally Public Subnets with Python

Published: (April 30, 2026 at 03:12 PM EDT)
2 min read
Source: Dev.to

Source: Dev.to

Day 5: Find Accidentally Public Subnets

The most common VPC misconfiguration is not a bad security‑group rule—it is a subnet using the VPC’s main route table when it shouldn’t.
Subnets without an explicit route‑table association inherit the VPC’s main route table. If that table has an Internet Gateway (IGW) route, those subnets are public whether you intended it or not.

Quick AWS CLI audit

# Get main route table for your VPC
MAIN_RT=$(aws ec2 describe-route-tables \
  --filters Name=vpc-id,Values=vpc-0abc123 \
           Name=association.main,Values=true \
  --query 'RouteTables[0].RouteTableId' --output text)

# Check if main RT has IGW route
aws ec2 describe-route-tables \
  --route-table-ids $MAIN_RT \
  --query 'RouteTables[0].Routes[?GatewayId!=`local`]'

# Find subnets with no explicit RT association
aws ec2 describe-subnets \
  --filters Name=vpc-id,Values=vpc-0abc123 \
  --query 'Subnets[].SubnetId' --output text | tr '\t' '\n' | while read SID; do
  ASSOC=$(aws ec2 describe-route-tables \
    --filters Name=association.subnet-id,Values=$SID \
    --query 'RouteTables[0].RouteTableId' --output text)
  if [ "$ASSOC" = "None" ]; then
    echo "WARNING: $SID uses main route table"
  fi
done

If the main route table has an IGW route and subnets are unassociated, fix both: remove the IGW route from the main table, and explicitly associate each subnet with the intended route table.

Tip: In Terraform, always use aws_route_table_association for every subnet. Never rely on the default association.

0 views
Back to Blog

Related posts

Read more »

Alert-Driven Monitoring

Teams usually associate the idea of infrastructure monitoring as a project to “hook up metrics” and “build dashboards”. In fact, in almost every monitoring plat...