Audit Your VPC: Find Accidentally Public Subnets with Python
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.