What is a VPC subnet - public vs private in one picture
A subnet in an AWS VPC is public if its route table sends internet-bound traffic (0.0.0.0/0) to an internet gateway, and private if it doesn't — that's the entire definition, and it's the one thing almost every "explainer" gets a little fuzzy on. Here's the part that trips people up even after they know the rule: "public" and "private" aren't properties of the subnet itself. They're not a checkbox you tick when you create it. A subnet is just a range of IP addresses sitting in one Availability Zone — it has no idea whether it's "public" or "private" until you point its route table somewhere. Change one route, and the exact same subnet, with the exact same instances still running inside it, flips from private to public without you touching a single server.
The one picture: a VPC, in a single frame
Jake runs a phone repair shop, and every few months he needs to spin something up on AWS for a small side tool — a repair-tracking app, a form for customers to check their ticket status. He doesn't want to read forty pages of documentation. He wants one picture that tells him where his stuff goes.
So here it is — the shape that almost every VPC on Earth eventually takes, drawn as boxes instead of paragraphs. One VPC (Virtual Private Cloud — think of it as your own private, walled-off section of AWS's network, like renting a whole floor of a building instead of a single desk in a shared office), one internet gateway at the top connecting that floor to the outside world, and inside it, two Availability Zones, each split into a public subnet on top and a private subnet underneath. Funnily enough, it's almost exactly the floor plan Jake once sketched on a napkin when he was thinking about expanding his shop into the empty unit next door — front counter facing the street, storage room tucked in the back with no window onto the road at all.
VPC — 10.0.0.0/16 (region: us-east-1)
igw-attached-to-vpc
↓ ↓
Availability Zone A
Public subnet — 10.0.1.0/24
Route: 0.0.0.0/0 → Internet Gateway
Holds: load balancer, NAT gateway
↓
Private subnet — 10.0.10.0/24
Route: 0.0.0.0/0 → NAT Gateway
Holds: app server, database
Availability Zone B
Public subnet — 10.0.2.0/24
Route: 0.0.0.0/0 → Internet Gateway
Holds: load balancer, NAT gateway
↓
Private subnet — 10.0.11.0/24
Route: 0.0.0.0/0 → NAT Gateway
Holds: app server, database
Two Availability Zones exist so that one data center problem doesn't take your whole app down — each subnet lives entirely inside one zone and can't span both.
That's it. That's the picture that covers roughly 80% of the VPCs anyone will ever build. Everything in the rest of this post is either zooming into one box, or covering the 20% of cases where the picture needs an extra row.
What a VPC actually is, in plain terms
🙋♂️ Jake's Reality Check
"Okay but why do I even need a VPC? Can't I just start an EC2 instance and be done with it?"
You already have one, whether you asked for it or not. Every AWS account gets a default VPC in each region, pre-configured with a public subnet in every Availability Zone and an internet gateway already attached, so you can launch something in ten minutes. The question isn't whether you have a VPC. It's whether the default one is the right shape for what you're building — and for anything that touches a database or customer data, it usually isn't.
A Virtual Private Cloud is a logically isolated slice of AWS's network that belongs only to your account. No other AWS customer's traffic can see into it by default, the same way your apartment's electrical wiring is isolated from your neighbor's even though you're both plugged into the same building's grid. When you create a VPC, you give it an IPv4 CIDR block — a range of private IP addresses written in slash notation, like 10.0.0.0/16. CIDR stands for Classless Inter-Domain Routing, and the number after the slash tells you how many addresses you get: a /16 gives you 65,536 addresses, a /24 gives you 256. Don't worry about memorizing the math — the two numbers that matter for a VPC are /16 (the biggest allowed, 65,536 addresses) and /28 (the smallest allowed, 16 addresses).
A VPC only exists in one AWS region, but it spans every Availability Zone in that region. An Availability Zone (often shortened to AZ) is one or more physically separate data centers with independent power, cooling, and networking — think of it as one branch of a bank rather than the whole bank. Ethan once put it to Jake in shop terms: an Availability Zone is like having a backup register wired in behind the counter, one that only kicks in if the main one crashes mid-Saturday rush — most customers never even notice it switched over. That regional-but-multi-zone shape is exactly why the picture above has two columns instead of one: AWS deliberately makes you think in terms of "what happens if this one zone goes dark," because it eventually will, even if only for an hour during maintenance.
What a subnet actually is
A subnet is a slice of your VPC's address range, and it must live entirely inside one Availability Zone — it can't stretch across two. That single rule is why you can't build a "public subnet" that automatically covers your whole region; you build one per zone, and if you want two zones of redundancy, you build two of each type.
Think of the VPC as an apartment building and the subnets as individual floors. The building has one street address (the VPC's CIDR block), but each floor has its own smaller range of unit numbers carved out of that address (the subnet's CIDR block). A subnet's CIDR block has to fall inside the VPC's CIDR block, and no two subnets in the same VPC are allowed to overlap.
Here's the detail that catches almost everyone by surprise the first time: you don't actually get every address in a subnet's range. In any subnet, AWS reserves the first four addresses and the very last one — five addresses total, gone before you even start. In a 10.0.0.0/24 subnet (256 addresses), that leaves you 251 usable ones. The reserved five are the network address, one for the VPC router, one for the DNS server, one held for future use, and the broadcast address at the top of the range. It's a small thing, but it's the reason a "256-address subnet" never actually fits 256 instances.
The single fact that decides public vs. private
Jake asked Ethan this exactly the way most people ask it: "So when I create the subnet, is there a public/private toggle somewhere I'm missing?" There isn't. AWS's own documentation is blunt about it — the subnet type is determined entirely by how you configure its routing, not by any setting on the subnet itself.
Every subnet is tied to a route table — a set of rules that decides where outbound traffic from that subnet gets sent. Every subnet you create is automatically associated with your VPC's main route table unless you point it somewhere else. A route table's entries are just pairs: "traffic headed to this destination, send it to this target." The one entry that flips everything is a route with a destination of 0.0.0.0/0 (which means "anywhere not otherwise listed" — it's the internet, essentially) pointed at an internet gateway.
✅ Why this is the one to hold onto
If a subnet's route table has 0.0.0.0/0 → internet gateway, it's public. If it doesn't, it's private. That's the whole rule, and everything else in this post — NAT gateways, isolated subnets, VPN-only subnets — is just a variation on what you point that one line at instead.
Ethan's take on this: "It's the single most under-explained fact in cloud networking, and it's also the most useful one. Once it clicks, you stop thinking of 'public subnet' as a category AWS invented and start seeing it as a label you're applying yourself, one route at a time."
And that's the reveal from the top of this post, spelled out in full: because the label lives entirely in the route table, you can take the private subnet from the picture above, add one route to it, and it becomes public — without moving a single instance, without recreating anything, without AWS asking you to confirm. The subnet's name, its console tags, whatever you called it when you created it — none of that matters. Only the route table does.
What lives in a public subnet, and what it actually needs
A public subnet's route table has a direct route to an internet gateway — a component you attach to your VPC once, which is horizontally scaled, redundant, and highly available, meaning you don't manage or scale it yourself; it doesn't create a bandwidth bottleneck no matter how much traffic passes through. For IPv4 traffic, the internet gateway also performs network address translation, swapping an instance's private IP for its public one on the way out and back on the way in.
Typical residents of a public subnet: a load balancer that needs to accept traffic from anywhere on the internet, a bastion host (a small, tightly locked-down instance whose only job is letting you SSH in from your own IP before hopping to private instances), and — this one surprises people — the NAT gateway itself, which needs to sit in a public subnet even though its whole purpose is serving private subnets.
🙋♂️ Jake's Reality Check
"So if I put my instance in a public subnet, anyone on the internet can just walk up to it?"
No — and this is the mistake that gets people hurt most often. A route to the internet gateway is necessary but not sufficient. The instance also needs a public IPv4 or IPv6 address assigned to it, and its security group has to allow the traffic in. Miss any one of the three and nothing gets through — which sounds safe, until you accidentally hit all three at once without meaning to.
That three-part requirement — route, public IP, and a security group rule that allows it — is worth committing to memory, because it's the source of two opposite and equally common mistakes. Some people put something in a public subnet, forget to assign it a public IP, and then spend an hour confused about why the internet "can't reach" a subnet that's supposedly public. Other people put a database in what they call their "private" subnet, except it was never actually configured as private — the route table still points at the internet gateway — and then compound it with a security group rule of 0.0.0.0/0 on the database port because a tutorial told them to "open it up for testing." Both mistakes trace back to treating the subnet's name as the security boundary instead of checking the actual route table.
Private subnets and how they reach the internet
A private subnet's route table has no direct route to an internet gateway. AWS's own guidance recommends private subnets as the default for protecting your resources — put things there, and give them a way out only when they genuinely need one.
That "way out" is usually a NAT gateway — a Network Address Translation service that lets instances in a private subnet start connections to the internet (to download an update, call an external API) while blocking the internet from starting connections back in. When you create a public NAT gateway, you place it in a public subnet and must associate an Elastic IP address with it at creation; you then route traffic from it to the VPC's internet gateway. The private subnet's own route table points 0.0.0.0/0 at the NAT gateway instead of at the internet gateway. There's also a private connectivity type, used to reach other VPCs or an on-premises network through a transit gateway rather than the open internet — worth knowing exists, even if a public NAT gateway covers most everyday cases.
Here's where Jake's business problem actually shows up. He built a small side project — a customer-facing repair status page backed by a tiny app server and database, both tucked safely into a private subnet the way every tutorial told him to. Three weeks later his AWS bill had a line item he didn't recognize, bigger than the EC2 instances themselves. The NAT gateway had been running the whole time, charging by the hour whether or not any traffic passed through it.
⚠️ What this actually breaks
Nothing breaks technically if you leave a NAT gateway running on a side project nobody's using — it just quietly bills you every hour, forever, until you notice or delete it. It's one of the easiest recurring charges to forget about precisely because it doesn't show up as a headline "instance" you'd think to shut down. AWS documents this bluntly: you're charged for each hour the NAT gateway is available and each gigabyte it processes, full stop — there's no idle exemption built in.
None of this means avoid private subnets — it means budget for the NAT gateway the moment you decide you need one. The cost section further down covers exactly what AWS itself recommends for keeping that bill down, plus a free alternative that solves a very specific, very common case.
The two subnet types almost nobody mentions
Most explanations stop at "public and private," and for a first project that's genuinely fine. But AWS's own documentation lists two more subnet types, and they solve real, specific problems.
Isolated subnets
An isolated subnet has no routes to anything outside its own VPC — not to an internet gateway, not to a NAT gateway, nothing. Resources inside can only talk to other resources inside the same VPC. This is the right home for a database that should never, under any circumstance, have a path to the internet even through a NAT gateway — a compliance requirement in some industries, and a sensible default for the most sensitive tier even when it isn't required. It's the digital equivalent of the storeroom Jake keeps locked at the back of his shop, with no door onto the street at all — his staff can walk in and grab stock any time, but nobody off the sidewalk can ever get near it.
VPN-only subnets
A VPN-only subnet has a route to a Site-to-Site VPN connection through a virtual private gateway, but no route to an internet gateway. This shows up when a company extends its own office or data center network into AWS over a secure tunnel — every resource in that subnet talks to the corporate network, never to the open internet, and traffic flows over the VPN connection rather than through a NAT gateway or internet gateway at all.
CIDR blocks and subnet sizing, without the math headache
You don't need to become a subnetting expert to run a VPC — you need to know the boundaries and a couple of safe defaults. Every VPC needs an IPv4 CIDR block sized between /16 (65,536 addresses) and /28 (16 addresses) at creation, and AWS recommends pulling that range from the private address space defined in RFC 1918 — the 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 ranges that are reserved for exactly this kind of internal, non-internet-routable use.
Subnets follow the same /16-to-/28 boundary, but their block has to fit entirely inside the VPC's range, and no two subnets in the same VPC can overlap. A common, boring, perfectly good starting pattern for a small VPC:
| What it is | CIDR block | Usable addresses |
|---|---|---|
| VPC | 10.0.0.0/16 | 65,536 total (before subnetting) |
| Public subnet, AZ A | 10.0.1.0/24 | 251 (256 minus 5 reserved) |
| Private subnet, AZ A | 10.0.10.0/24 | 251 |
| Public subnet, AZ B | 10.0.2.0/24 | 251 |
| Private subnet, AZ B | 10.0.11.0/24 | 251 |
Notice the gap between .1/.2 (public) and .10/.11 (private) — it's not required, but leaving room in the numbering is a habit worth adopting early, so you can slot in a third or fourth subnet tier (a dedicated database layer, for instance) later without renumbering everything you already built.
Security groups vs. network ACLs: which one actually protects a subnet
Public and private are about where traffic is allowed to route to. Security groups and network ACLs are about what traffic is allowed through once it's routed there — and mixing these two ideas up is how people end up believing a private subnet alone is "secure enough."
A security group attaches to individual resources, like an EC2 instance's network interface, and only allows traffic you explicitly permit — everything else is denied by default, and it's stateful, meaning if you allow an inbound request, the matching response is automatically allowed back out without a separate rule.
A network ACL, by contrast, attaches to the whole subnet and evaluates every resource inside it the same way. It can both allow and explicitly deny traffic. Every subnet is automatically associated with a network ACL — the default one, which allows all inbound and outbound traffic until you change it.
✅ Why this is the one to use
Security groups handle nearly everything most people need — AWS's own guidance says security groups can meet your needs in most cases, and only recommends network ACLs on top when you specifically want a second, subnet-wide layer of defense. Start with security groups. Add network ACLs deliberately, not by default.
A real multi-tier layout, worked through end to end
Here's how the "one picture" from earlier plays out when Jake actually builds his repair-status site. A customer types in a ticket number, a web server shows them the status, an app server checks a database behind it. Nobody outside needs a direct line to the database — ever.
| Layer | Subnet type | Why |
|---|---|---|
| Load balancer | Public | Needs to be reachable from any customer's browser, anywhere |
| App server | Private | Only the load balancer needs to reach it; it occasionally needs outbound access for updates, via NAT |
| Database | Private (or isolated) | Only the app server needs to reach it; almost never needs outbound internet access itself |
| Bastion host | Public | You need a way in from your own laptop when something needs a manual look |
One layer at a time, none of it is complicated. The load balancer takes the hit from the internet so nothing behind it has to. The app server does the thinking. The database just answers questions from the app server and never talks to anyone else. That's the whole architecture — three tiers, two subnet types, and a bastion host for the rare moment someone actually needs to log in by hand.
The mistakes that show up over and over
"Wait, so half the tutorials online are telling me my database is fine in a public subnet as long as I don't give out the URL?" That's roughly what Jake asked after reading a few older guides. The honest answer is that plenty of published advice is wrong, or at least dangerously incomplete, on exactly this point.
"Nobody knows the address, so it's safe"
Public subnets don't stay secret. Automated scanners sweep the public IPv4 address space constantly, probing for open ports on common services — this isn't a targeted attack, it's background noise that finds every exposed thing eventually, often within hours. Obscurity was never the security layer; the route table and the security group are.
"I created it in the 'private' subnet, so it's private"
The name you typed in the console is a label for your own benefit. AWS doesn't enforce anything based on it. If that subnet's route table still points at an internet gateway — maybe because it was cloned from a public one and the route was never removed — the subnet behaves exactly like a public one no matter what it's called.
"A public subnet means the internet can reach everything in it"
Covered above, but worth repeating because it's the mirror-image mistake: a route to the internet gateway is necessary, not automatic access. No public IP on the instance, or a security group that blocks the traffic, and the "public" subnet is still effectively closed off for that resource.
How to check whether a subnet is public or private, right now
Don't trust the name in the console. Check the route table — it takes under a minute.
- Open the Amazon VPC console and go to Subnets in the navigation pane. Select the subnet you want to check.
- Look at the Route table tab for that subnet. If it doesn't show a custom one, note that it's using the VPC's main route table.
- Open that route table and look at its Routes tab.
- Scan for a row with a destination of
0.0.0.0/0(or::/0for IPv6) whose target starts withigw-. If it's there, the subnet is public. If the target instead starts withnat-, it's private with outbound internet access through NAT. No matching row at all means it's private with no internet path — or isolated, depending on what else is (or isn't) in that table. - If you're checking an EC2 instance specifically, also confirm it has a public IPv4 or IPv6 address under Networking, and that its security group allows the traffic you're expecting. All three have to line up.
How to actually flip a subnet from private to public (or back)
To turn a private subnet into a public one, you need an internet gateway attached to the VPC and one route added:
- In the VPC console, go to Internet gateways. If your VPC doesn't already have one attached, create one and attach it to your VPC — a VPC can only have one internet gateway at a time.
- Go to Route tables and select the route table associated with the subnet you're changing (create a new, dedicated route table first if it's currently sharing one with subnets you don't want to affect).
- Open the Routes tab, choose Edit routes, then Add route.
- Set the destination to
0.0.0.0/0and the target to your internet gateway. Save. - The subnet is now public by definition — but any instance already running inside it still won't be reachable until you also give it a public IP address and open the right ports in its security group.
To go the other direction — turning a public subnet private — remove that same 0.0.0.0/0-to-internet-gateway route from its route table. If anything inside still needs outbound internet access, add a route to a NAT gateway instead before you remove the internet gateway route, or everything in that subnet loses internet access the moment you save.
⚠️ What this actually breaks
If a route table is shared across several subnets and you edit it to add or remove the internet-gateway route, every subnet using that route table changes at once — not just the one you meant to touch. Give subnets that need different treatment their own dedicated route tables before you start editing.
The cost angle nobody mentions until the bill arrives
A VPC itself is free. Subnets are free. Route tables are free. Running instances, load balancers, and databases inside all of that costs whatever those specific services cost — the VPC layer adds nothing on its own, with exactly two exceptions that catch people off guard: NAT gateways and interface VPC endpoints, both of which carry their own hourly and per-gigabyte charges. For the current exact rate in your region, AWS's own VPC pricing page is the source to check — the figures move over time and this post won't try to freeze a snapshot of them.
AWS's documentation gives two specific ways to bring the NAT gateway bill down, and they're both worth doing before anything fancier:
| Strategy | What it targets | Effect |
|---|---|---|
| Keep resources in the same AZ as the NAT gateway | Cross-AZ data transfer charges | Avoids paying to move traffic between zones before it even reaches the NAT gateway; alternatively, run one NAT gateway per AZ that has resources |
| Use a VPC endpoint for AWS-service traffic | NAT gateway data-processing charges | If most of your NAT gateway's traffic is going to AWS services that support gateway or interface endpoints, route it through the endpoint instead and skip the NAT gateway entirely for that traffic |
Here's the fix Jake actually used once Ethan pointed it out: if a private subnet's only reason for needing a NAT gateway is reaching Amazon S3 or DynamoDB, a gateway-type VPC endpoint covers exactly that case with no hourly charge and no data-processing charge at all. You add a route to the endpoint in the subnet's route table, and traffic to S3 or DynamoDB never touches the NAT gateway or the public internet — it stays entirely inside AWS's own network.
✅ Why this is the one to use
If your private subnet's outbound traffic is mostly S3 or DynamoDB calls, a gateway endpoint is strictly better than routing that traffic through a NAT gateway — same privacy, no extra charge for that traffic, one less thing that can fail. Reach for it before reaching for a second NAT gateway to handle more volume.
It won't cover everything — a NAT gateway is still the right tool the moment your private subnet needs to reach something outside AWS entirely, like a third-party API or a software update server. But for the specific case of talking to S3 or DynamoDB, it's money left on the table if you skip it.
When nothing works: the honest troubleshooting list
You've followed every step above and something still isn't reachable, or a private instance still has no internet access. Walk this list in order — it covers the cases people actually get stuck on, not the obvious ones.
An instance in a "public" subnet still isn't reachable from the internet. Check all three requirements again, individually: route table has the internet-gateway route (not just attached to the VPC — actually routed from that specific subnet's table), the instance itself has a public IPv4 or IPv6 address, and the security group allows inbound traffic on the port you're testing. It's almost always one of these three, and it's almost never the internet gateway itself, since that component doesn't have settings to misconfigure beyond being attached or not.
A private instance can't reach the internet at all, and you expected it to. Confirm a NAT gateway actually exists, that it's in the available state (not still provisioning), that it sits in a public subnet with its own working route to the internet gateway, and that your private subnet's route table points 0.0.0.0/0 at that NAT gateway's ID specifically — not at the internet gateway by mistake, which is a surprisingly common copy-paste error when someone duplicates a public subnet's route table to use as a starting point for the private one.
Everything looks right but connections are dropping intermittently. If you're relying on a single NAT gateway for multiple Availability Zones — routing AZ B's private subnet through a NAT gateway that physically lives in AZ A — you've created a cross-zone dependency, and AWS's own guidance names that same cross-AZ traffic as one of the two main levers for cutting NAT gateway costs, for exactly this reason. It'll work, but it isn't the resilient pattern, and it isn't the cheapest one either.
⚠️ What we can't fix for you
If a NAT gateway in the only Availability Zone you're using goes down for maintenance or an AZ-level issue, every private subnet depending on it loses internet access until it recovers or you provision a replacement — there's no built-in failover between AZs unless you've deliberately built one NAT gateway per zone. A single NAT gateway is a single point of failure by design, not a bug.
Frequently asked questions
Is a subnet public or private by default when I create it?
It's private in effect since a newly created subnet has no route to an internet gateway until you add one. It automatically attaches to the VPC's main route table, and whether that main route table is public or private depends on what's already in it, so check it rather than assuming.
Can a subnet have a route to an internet gateway but still not work as "public"?
Yes — if the internet gateway isn't actually attached to the VPC, or if the route table with that entry isn't the one associated with the subnet you're testing.
Does a public subnet mean my EC2 instance is automatically reachable from the internet?
No. The subnet's route is only one of three requirements — the instance also needs a public IP address, and its security group has to explicitly allow the inbound traffic. All three have to be true at once.
What's the actual difference between a NAT gateway and an internet gateway?
An internet gateway lets a public subnet's resources both send traffic out to the internet and receive connections initiated from the internet. A NAT gateway only lets a private subnet's resources start outbound connections — nothing on the internet can initiate a connection back to them through it.
Can a private subnet reach the internet at all?
Only if you give it a path — typically a NAT gateway sitting in a public subnet, or for IPv6-only outbound traffic, an egress-only internet gateway. Without either, a private subnet has no route out and stays fully isolated from the internet.
Why is my NAT gateway bill so much higher than I expected?
It bills for every hour it's available, whether or not it's carrying traffic, and for every gigabyte it processes in either direction, on top of standard data transfer rates. A gateway left running on a quiet side project adds up over weeks even with almost no real usage.
Is there a free way for a private subnet to reach S3 or DynamoDB?
Yes — a gateway-type VPC endpoint. It has no hourly charge and no data-processing charge for traffic to those two services, and keeps that traffic off both the NAT gateway and the public internet.
Can I convert a public subnet into a private one later?
Yes — remove the 0.0.0.0/0-to-internet-gateway route from its route table. Add a NAT gateway route first if anything inside still needs outbound internet access, or it'll lose that access the moment the internet-gateway route is removed.
How many subnets do I actually need for a basic web app?
A resilient minimum is four: one public and one private subnet in each of two Availability Zones. You can technically run everything in one public subnet in one zone, but a single zone going down would take the whole app with it.
What is an isolated subnet, and when would I use one?
A subnet with no routes to anything outside its own VPC — not even through a NAT gateway. Use it for resources, most often databases, that should never have any outbound path to the internet under any circumstance.
Does every subnet need its own route table?
No — subnets can share a route table, and every new subnet starts out attached to the VPC's main route table automatically. But subnets that need different routing behavior (one public, one private) need to be associated with different route tables, since a shared table applies the same routes to everything using it.
What's the smallest and largest subnet I can create?
Between a /28 netmask (16 addresses, 11 usable after AWS's five reserved) and a /16 netmask (65,536 addresses), and a subnet can never be larger than the VPC's own CIDR block it's carved out of.
Do I need a NAT gateway in every Availability Zone?
Not technically — one NAT gateway can serve private subnets in other zones. But that creates a cross-zone dependency, extra cross-AZ data transfer charges, and AWS's own documentation lists this exact pattern as one of the two levers for cutting NAT gateway costs. One NAT gateway per zone is the resilient, if pricier, pattern.
What happens to my private subnet if the NAT gateway fails?
Everything inside loses outbound internet access until the NAT gateway recovers or you provision a new one. Traffic between resources inside the VPC is unaffected — it's only the path out to the internet that depends on the NAT gateway.
Is a bastion host the same thing as a public subnet?
No — a bastion host is an instance you deliberately place inside a public subnet, tightly restricted with a security group that usually only allows your own IP address, so you have a controlled entry point for reaching resources in private subnets. The public subnet is just where it lives.
Should a database ever sit in a public subnet?
Essentially never, for anything handling real or sensitive data. Even with a locked-down security group, a database in a public subnet is one misconfigured rule away from being exposed to the entire internet. A private or isolated subnet removes that entire category of mistake by making the internet unreachable in the first place, regardless of what the security group says.
Revision note. Written September 2026 BUT — it'll need a fresh look if AWS restructures how NAT gateways or gateway endpoints are billed. If you're staring at a route table right now trying to figure out why something won't connect, you're closer than it feels — it really does come down to that one line.
π‘ Recommended AWS Foundations Reading
Master the core building blocks of AWS infrastructure, networking, and security:
- πΊ️ Regions vs. Availability Zones — The physical map that fixes half of your latency and redundancy bugs.
- π Decoding AWS ARNs — How to read the exact address syntax for any resource across accounts and regions.
- π‘️ Shared Responsibility Model — Who fixes what when an AWS service fails or leaks.
- π Public vs. Private Subnets — Visualizing traffic flow and network isolation in a VPC.
- πͺ Internet Gateway vs. NAT Gateway — Outbound internet routing without hidden cost surprises.
- π§± AWS Security Groups — Stateful firewall rules explained in plain English.
- π Service-Linked Roles — The permissions AWS automatically creates and manages for you.
- π₯️ EC2 Instance Profiles — How EC2 instances access services without hardcoded access keys.
- π¨ Root User vs. IAM User — Why you should lock away root credentials immediately.
- π AWS MFA Setup Guide — Clear the console nagging banner and secure your account in 3 minutes.