AWS VPC for Developers — Private Subnets and Security Groups Done Right
> cd .. / HUB_EDITORIALE
Sviluppo di siti web

AWS VPC for Developers — Private Subnets and Security Groups Done Right

[2026-08-03] Author: Ing. Calogero Bono
> share
Zenithby Meteora Web The operating system for your business. Social, clients, bookings and invoices in one platform. Gyms, barbers, professionals. Discover Zenith Free demo · no card

Your team just pushed a service to production on EC2, and the next day someone calls because the dashboard is unreachable. You check the logs: the database is exposed on a public port, a security group open to 0.0.0.0/0, and everything lives in a subnet that was never meant to be public. This is not a rare scenario: we see it often when a project grows fast and AWS networking gets improvised. If you are reading this, you probably already have a hint of the problem: the default VPC is not built for production, and private subnets are not private by magic, but by configuration.

This guide starts from the concrete problem: how to design a VPC that truly separates what must be public from what must stay internal, and how to use security groups without turning them into a sieve. No academic theory: subnets, route tables, internet gateways, NAT gateways, and security groups explained with real examples, copy-paste commands, and a final checklist to avoid mistakes.

Why the Default VPC Is Not Good Enough for Production?

When you create an AWS account, the default VPC gives you everything right away: subnets in every availability zone, an attached internet gateway, and configured route tables. It seems convenient, but it is a trap. Every instance you launch in that VPC has a public IP and a route to the internet. The database, the backend, the frontend: everything is reachable from the outside if the security group allows it. And it often does, because people in a hurry open ports and think they will close them later.

We, at Meteora Web, think like former accountants: if a configuration error costs you a data breach, the price is not just technical, it is economic. The default VPC is like an office with a single door open to the street: it works until someone walks in who should not. In production, the VPC must be designed like a building with distinct zones: a public reception, internal offices, and a vault.

Sponsored Protocol

How Do Public and Private Subnets Work in AWS?

The difference between a public and a private subnet is not an intrinsic property of the subnet itself, but of its route table. A subnet is public if its route table has a route to 0.0.0.0/0 pointing to an internet gateway. It is private if that route points to a NAT gateway or does not exist at all. It sounds trivial, but it is the concept that unlocks everything else.

Practical example: you have a web server that must receive HTTPS traffic from the internet, and a database that must only talk to the web server. The web server goes in a public subnet, with an internet gateway in the route table. The database goes in a private subnet, with no route to the internet. If someone tries to reach the database from the outside, they cannot: there is no network path, it is not a firewall issue.

# Create a VPC with two public and two private subnets (us-east-1)
aws ec2 create-vpc --cidr-block 10.0.0.0/16
# Note the VpcId, then create the subnets
aws ec2 create-subnet --vpc-id vpc-xxxx --cidr-block 10.0.1.0/24 --availability-zone us-east-1a
aws ec2 create-subnet --vpc-id vpc-xxxx --cidr-block 10.0.2.0/24 --availability-zone us-east-1b
aws ec2 create-subnet --vpc-id vpc-xxxx --cidr-block 10.0.10.0/24 --availability-zone us-east-1a
aws ec2 create-subnet --vpc-id vpc-xxxx --cidr-block 10.0.11.0/24 --availability-zone us-east-1b
# The first two will be public, the second two private. The difference comes later, with route tables.

How to Configure an Internet Gateway and a NAT Gateway in the VPC?

The internet gateway is the entry and exit point to the world. Without it, no public traffic. The NAT gateway, on the other hand, is the controlled exit for private resources: it allows instances in private subnets to perform system updates or API calls to the outside, but prevents anyone from the outside from initiating them. It is a concept our clients struggle with at first: the database can download packages, but it cannot be contacted. Like an office that can send mail but not receive it.

Sponsored Protocol

Practical Steps to Connect Public Subnets to the Internet

First, create an internet gateway and attach it to the VPC. Then modify the route table associated with the public subnets, adding a 0.0.0.0/0 route to the IGW. For private subnets, create a NAT gateway in a public subnet (it needs an Elastic IP) and add a 0.0.0.0/0 route to the NAT in the private route table. Note: the NAT gateway costs about $32 per month. If budget is a concern, you can use a self-managed NAT instance, but we prefer the managed gateway: less maintenance, less risk.

# Create an Internet Gateway and attach it to the VPC
aws ec2 create-internet-gateway
aws ec2 attach-internet-gateway --internet-gateway-id igw-xxxx --vpc-id vpc-xxxx
# Create a public route table and add the route to the IGW
aws ec2 create-route-table --vpc-id vpc-xxxx
aws ec2 create-route --route-table-id rtb-xxxx --destination-cidr-block 0.0.0.0/0 --gateway-id igw-xxxx
# Associate the route table with the public subnets
aws ec2 associate-route-table --route-table-id rtb-xxxx --subnet-id subnet-xxxx

How to Use Security Groups to Protect EC2 Instances?

Security groups are the virtual firewall at the instance level. They work like a bouncer: they decide who enters and who leaves, but only if configured well. The problem is that many treat them like a shopping list: they open random ports, use 0.0.0.0/0 for everything, and then wonder why attacks come in. The golden rule is the principle of least privilege: open only what is needed, only to whom it is needed.

Sponsored Protocol

A common mistake we see in projects that come to us: the database security group open to 0.0.0.0/0 on port 3306. It takes only a few minutes with a scanner to find MySQL databases exposed on the internet. The correct way is to reference the web server's security group, not the IP. This way, only instances with that security group can talk to the database, regardless of their IP.

How to Reference a Security Group from Another for the Database

Suppose you have a web instance with security group sg-web and a database with security group sg-db. On sg-db, open port 3306 only for inbound traffic from sg-web. You do not need to know the web server's IP: AWS resolves the relationship at the group level. If the web server changes IP, the rule keeps working. This is the professional way to handle internal traffic.

# Add a rule to the database security group
aws ec2 authorize-security-group-ingress \
    --group-id sg-db \
    --protocol tcp \
    --port 3306 \
    --source-group sg-web
# Only instances with sg-web can reach the database on 3306

What Mistakes to Avoid When Designing the VPC?

The first mistake is not planning the CIDR. Using 10.0.0.0/16 is fine, but if you need to peer with another VPC in the future and the ranges overlap, you have a serious problem. Choose a range that is wide but not too wide, and leave room to grow. The second mistake is forgetting VPC endpoints: for services like S3 or DynamoDB, you can avoid internet traffic by using a gateway or interface endpoint. It costs less, is more secure, and reduces latency.

The third mistake is never testing the configuration. You create the VPC, launch the instances, and only discover in production that the NAT gateway does not work or that the security group blocks legitimate traffic. We always test with a trial instance: launch a machine in a private subnet, try to ping a public IP, and verify that traffic goes through the NAT. If it does not work, you find out before, not after.

Sponsored Protocol

How to Test Connectivity from a Private Subnet

Launch an instance in a private subnet, connect via Session Manager (no SSH key needed), and try to reach the internet. If the NAT is configured correctly, the ping command works. If not, check the route tables and make sure the NAT is in a public subnet with an Elastic IP attached. A detail many forget: the NAT gateway must have a route to the internet, otherwise it cannot forward traffic.

# From an instance in a private subnet, test connectivity
ping -c 4 8.8.8.8
# If it does not respond, check the route tables of the private subnet
aws ec2 describe-route-tables --route-table-ids rtb-private

How to Reduce VPC Costs Without Compromising Security?

The NAT gateway is the most expensive component of the VPC, but you can reduce costs by using a self-managed NAT instance on a small EC2. It costs less but requires maintenance: you have to handle updates and availability. Alternatively, for non-critical workloads, you can eliminate the NAT altogether and use VPC endpoints for AWS services. If your traffic to the internet is minimal, a NAT gateway is a waste.

Another strategy is consolidating resources: you do not need a VPC for development and another for production if you can use separate subnets in the same VPC. We often do this for clients with limited budgets: same VPC, separate subnets, different security groups. The risk of contamination is low if the rules are clear and documented.

How to Use VPC Endpoints to Reduce Internet Traffic

For S3 and DynamoDB, create a gateway endpoint. It is free and routes traffic directly over the AWS network, without going through the internet. For other services like EC2 API or Systems Manager, use an interface endpoint: it costs a few cents per hour but eliminates the need for a NAT for those calls. The result is a more secure and cheaper VPC.

Sponsored Protocol

# Create a VPC endpoint for S3 (gateway endpoint)
aws ec2 create-vpc-endpoint \
    --vpc-id vpc-xxxx \
    --service-name com.amazonaws.us-east-1.s3 \
    --route-table-ids rtb-private
# Traffic to S3 now goes over the AWS network, not the internet

What to Do Now

If you are managing a default VPC or an improvised configuration, do not wait for something to break. Here are the concrete actions to take right now:

1. Audit route tables: check every subnet and verify that routes to 0.0.0.0/0 point only where they should. If you find a private subnet with a route to the internet gateway, fix it.

2. Review security groups: look for rules with 0.0.0.0/0 on non-HTTP/HTTPS ports. If you find the database open to the world, close it and reference the application's security group instead.

3. Test connectivity: launch an instance in a private subnet and verify the NAT works. If you do not have a NAT, decide whether to create one or use VPC endpoints.

4. Document the configuration: write a VPC diagram with subnets, route tables, and security groups. If someone needs to intervene, they must understand the structure in five minutes.

5. Dive deeper with our pillar guide: if you want the full picture on AWS infrastructure, start with our AWS pillar guide for developers and then come back here for VPC details.

The VPC is not a technical detail: it is the foundation of your entire stack's security. Getting it wrong means exposing client data, and the price is not just technical, it is reputational and economic. We know it well: we come from accounting, and numbers never lie.

> share
Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // DIGITAL AGENCY

We build the digital presence your business deserves.

Websites, social media, online advertising, e-commerce and high-performance hosting, engineered with method by computer engineers in Sciacca, for all of Italy.

> MW_JOURNAL

> READ_ALL()