AWS Default VPC vs Custom VPC: Differences, Risks, and When to Use Each
AWS creates a default VPC in every region the moment you open an account. You can launch an EC2 instance without touching a single networking setting: no subnets to create, no internet gateway to configure. That convenience is real. So is the risk. Every default VPC is fully public with no private subnets, uses the same fixed CIDR block across every AWS account in the world, and blocks VPC peering in multi-account setups. Use the default VPC for learning and throwaway testing. Build a custom VPC for anything that matters.
Simple explanation
Default VPC: AWS’s pre-built network. Ready the moment your account exists. All subnets are public. No private networking. Same IP range in every account and every region. Good for running your first EC2 instance. Not for production.
Custom VPC: Your own network design. You choose the IP range, create public and private subnets, attach an internet gateway only where it makes sense, and control every routing decision. More setup upfront, but you actually own the network.
The default VPC is like a furnished hotel room. Move in immediately, everything works, but the door code is the same as every other guest’s and you cannot change the floor plan. A custom VPC is an empty flat you fit yourself. More work before you move in, but the locks are yours and nothing was left behind by the previous tenant.
How the default VPC works
When AWS activates a new account, it creates one default VPC per region automatically. Here is exactly what it contains:
- CIDR block
172.31.0.0/16: fixed, the same across every AWS account in every region, worldwide. - One
/20public subnet per Availability Zone: created automatically in every AZ in the region. - An internet gateway, already attached: traffic can flow in and out of the VPC from the first second.
- A main route table with a
0.0.0.0/0route to the internet gateway: every subnet is publicly routable by default. - Auto-assign public IPv4 enabled on every default subnet: any EC2 instance you launch receives a public IPv4 address automatically, unless you override the subnet’s auto-assign behavior.
- DNS support and DNS hostnames enabled: services that require DNS resolution work immediately.
- A default security group: allows all outbound traffic and all inbound traffic from resources in the same security group.
The practical result: launch an EC2 instance into the default VPC and it gets a public IP and can be reached from the internet. That is exactly what makes it useful for quick experiments and exactly what makes it wrong for production. For a deeper look at how this all fits together, see VPC Networks Explained.
Every subnet in the default VPC routes directly to the internet gateway. The only thing standing between your resources and the public internet is your security group rules. One misconfigured rule and your database or internal service is exposed. That is one layer of defense, not defense in depth.
Default VPC vs custom VPC: side by side
| Default VPC | Custom VPC | |
|---|---|---|
| Setup | Automatic, already exists | You create it |
| CIDR choice | Fixed: 172.31.0.0/16 | You choose (e.g., 10.0.0.0/16) |
| Subnet design | One public subnet per AZ | You define public and private subnets |
| Internet exposure | All subnets route to the internet | Only subnets you explicitly connect to an IGW |
| Private subnet support | None | Yes, you create them |
| Routing control | Pre-configured, all traffic to internet | You define every route table |
| Peering / multi-account | Rarely possible (CIDRs overlap) | Yes, with planned CIDR ranges |
| DNS enabled | Yes, by default | You enable it (a simple flag) |
| Best use case | Tutorials, throwaway testing | Staging, production, databases, anything persistent |
| Production suitable | No | Yes |
When to use each
Following an AWS tutorial or documentation walkthrough. Running an AWS CLI command for the first time and you just need an instance running. Spinning up a throwaway instance to test something for 20 minutes. Learning AWS in a personal account with no sensitive data.
Use a custom VPC for everything else:
- Staging environment: needs to mirror production, which means private subnets and controlled routing.
- Production application: app servers and databases should live in private subnets, not directly on the internet.
- RDS database: databases belong in private subnets with no public routing. Note that RDS has a separate “Publicly accessible” setting controlling whether it gets a public endpoint. Placing RDS in a private subnet is the right baseline regardless of that setting.
- Multi-account architecture: if you ever need to peer VPCs across accounts, the default VPC’s
172.31.0.0/16will conflict with every other account’s default VPC. See VPC Peering for CIDR requirements. - Hybrid networking: connecting to on-premises infrastructure over Site-to-Site VPN or Direct Connect requires an IP space that does not conflict with your corporate network.
How to build a production-ready custom VPC
A solid custom VPC follows a two-tier subnet model at minimum: public subnets for load balancers and NAT gateways, and private subnets for application servers, databases, and anything that should not be directly internet-facing.
The goal below is a VPC with a 10.0.0.0/16 CIDR, one public and one private subnet in each of two AZs, and an internet gateway wired to the public subnets only.
# 1. Create the VPC
aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=prod-vpc}]'
# Save the VpcId from the output as VPC_ID
# 2. Enable DNS support and hostnames (required by most AWS services)
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-support
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames
# 3. Create public subnets in two AZs
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-1a}]'
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-1b}]'
# 4. Create private subnets in two AZs
aws ec2 create-subnet \
--vpc-id $VPC_ID --cidr-block 10.0.11.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-1a}]'
aws ec2 create-subnet \
--vpc-id $VPC_ID --cidr-block 10.0.12.0/24 \
--availability-zone us-east-1b \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-1b}]'
# 5. Create an internet gateway and attach it to the VPC
aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=prod-igw}]'
# Save as IGW_ID
aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
# 6. Create a public route table with a route to the internet gateway
aws ec2 create-route-table \
--vpc-id $VPC_ID \
--tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rt}]'
# Save as PUBLIC_RT_ID
aws ec2 create-route \
--route-table-id $PUBLIC_RT_ID \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id $IGW_ID
# 7. Associate the public subnets with the public route table
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_1A --route-table-id $PUBLIC_RT_ID
aws ec2 associate-route-table --subnet-id $PUBLIC_SUBNET_1B --route-table-id $PUBLIC_RT_IDPrivate subnets have no route to the internet gateway. That is intentional. To let private instances download patches or reach external APIs without being reachable from the internet, create a NAT Gateway in a public subnet and add a route in the private route table pointing 0.0.0.0/0 to it. Outbound traffic gets through; nothing from the internet can reach private resources directly.
For subnet design and CIDR planning, see Subnets in AWS. For how route tables control traffic flow, see Route Tables in AWS.
Common mistakes
Launching a production database or internal API into the default VPC and assuming security group rules make it safe. They do not. Security groups are stateful and useful, but they are one rule misconfiguration away from full exposure. Private subnets eliminate that attack surface entirely. See Network Security Best Practices.
- Treating the default VPC as production-ready. Its entire design — public subnets, all-internet routing, auto-assigned public IPs — is the opposite of what production needs. Security group rules can reduce exposure, but they are a single layer of defense with no private subnet isolation underneath.
- Not planning CIDR ranges before creating custom VPCs. Create two custom VPCs with
10.0.0.0/16, one in account A and one in account B, and you can never peer them. Decide on a CIDR allocation strategy before you create anything. A common pattern: each AWS account gets a unique/16block from your organization’s address space. - Relying only on security groups instead of subnet and routing design. Security groups are stateful and useful, but they are not a substitute for private subnets. Defense in depth means multiple layers: put your database in a private subnet with no public route, and also restrict its security group. Not just one or the other.
- Forgetting that services can fall back to the default VPC. CloudFormation templates, CLI commands, and third-party tools that do not specify a VPC often land in the default VPC. Sensitive resources can end up in a network you did not intend. Deleting the default VPC from production accounts closes that door entirely, and it can be recreated later if needed.
- Assuming “default” means “best practice”. AWS named it the default VPC because it is the starting point, not the recommended approach. Many experienced teams delete it from every production account as part of their baseline account setup.
- Misunderstanding public IP assignment. In the default VPC, every launched EC2 instance gets a public IP automatically because auto-assign is enabled at the subnet level. In a custom VPC, public IPs are opt-in per subnet. This distinction matters when debugging connectivity. See Private vs Public IP Addresses.
Quick recommendation
Use the default VPC only for tutorials, throwaway instances, and learning exercises in a personal account with nothing sensitive.
Use a custom VPC for anything persistent, shared, sensitive, or production-facing: staging, databases, internal services, and anything that might eventually connect to other VPCs or on-premises networks.
Setup takes under 10 minutes with the CLI. The cost of skipping it is a network you will eventually have to migrate away from.
Summary
- AWS creates one default VPC per region automatically, with CIDR
172.31.0.0/16, the same block across every AWS account worldwide. - All default subnets are public. EC2 instances launched into them receive public IPv4 addresses by default.
- There are no private subnets in the default VPC. Security groups are the only protection layer.
- The fixed CIDR makes VPC peering across accounts impossible in multi-account setups.
- Use the default VPC for learning and short-lived experiments only. Never for production.
- Custom VPCs give you private subnets, controlled routing, flexible CIDR ranges, and multi-account compatibility.
- Deleting the default VPC from production accounts is common in hardened environments. It can be recreated if needed.
- Always enable DNS support and DNS hostnames when creating a custom VPC. Most AWS services require them.
Frequently asked questions
Should I delete the default VPC?
Many security-focused teams delete it from production accounts to prevent engineers from accidentally deploying into it. Check that no services are using it first, because some AWS tools fall back to the default VPC when no VPC is specified. Deleting it is common practice in hardened environments but not a universal requirement.
Can I recreate the default VPC if I delete it?
Yes. Go to VPC in the AWS console, then Actions, then Create Default VPC. Or run: aws ec2 create-default-vpc --region us-east-1. AWS recreates it with the standard 172.31.0.0/16 CIDR and default subnets in each AZ.
Can I make the default VPC private?
Not cleanly. You can modify route tables and security groups, but the default VPC was built as a fully public network. Every subnet has auto-assign public IPv4 enabled and routes to an internet gateway. Retrofitting it to behave like a private network is more work and more fragile than building a new custom VPC from scratch.
Does the default VPC cost money?
The VPC itself is free. You only pay for resources you launch inside it: EC2 instances, NAT gateways, data transfer, and so on. An empty default VPC costs nothing.
Is it okay to use the default VPC for staging or production?
No. The default VPC has no private subnets, uses the same CIDR across every AWS account, and makes every EC2 instance publicly routable by default. That is the wrong baseline for any workload you care about. Build a custom VPC for staging, production, databases, and anything persistent.