Ravindra BagaleCourses & study guides Track your progress

Guides

How to Set Up a NAT Gateway for a Private Subnet in AWS

To give a private subnet outbound internet access, create a NAT gateway in a public subnet (VPC → NAT gateways → Create NAT gateway, connectivity type Public, Allocate Elastic IP), wait until it is Available, then add the route 0.0.0.0/0 → nat-… to the private subnet's route table. Instances in the private subnet can then run yum and call APIs, but nobody on the internet can start a connection to them. A NAT gateway is billed per hour and per GB, so delete it after the lab.

Come on, friends! People in the society's inner wing can go out and bring things back, but outsiders don't come straight to their doors – everything comes through the society office. The NAT gateway is that office: private servers send requests out, the answer comes back, but nobody from the internet can get in. Note: this office charges money – by the hour.

Quick answer

VPC → NAT gateways → Create NAT gateway
    Name: society-nat   Subnet: web-public-1a (PUBLIC)   Connectivity type: Public
    Elastic IP allocation ID: Allocate Elastic IP  →  Create NAT gateway
Route tables → private-rt → Edit routes → Add route
    0.0.0.0/0  →  NAT Gateway  →  society-nat

Test from a private instance (through the bastion):

curl -s https://checkip.amazonaws.com      # prints the NAT gateway's Elastic IP
sudo yum install -y htop                    # package downloads now work

Clean up: Delete NAT gateway → wait for Deleted → EC2 → Elastic IPs → Release.

What do I need before creating a NAT gateway?

  • A VPC with a public subnet (route 0.0.0.0/0 → igw-…) and a private subnet with its own route table. See Public vs private subnet.
  • A free Elastic IP slot (default quota: 5 per Region).
  • A cost check: a NAT gateway is charged for every hour it exists plus every GB it processes, and it is not part of the free tier. Set up a billing alarm and budget first. Exact prices depend on the Region; check the Amazon VPC pricing page.

How does a NAT gateway work?

How a NAT gateway gives a private subnet outbound internet The app server in the private subnet runs yum install. Its route table sends 0.0.0.0/0 to the NAT gateway, which sits in the public subnet with an Elastic IP. The NAT gateway replaces the private source address with its Elastic IP and sends the request through the internet gateway to the package repository; the reply comes back the same way. A new connection started from the internet towards the NAT gateway is refused. Public subnet NAT GWElastic IP Private subnet App10.0.2.10 0.0.0.0/0 → nat-… IGW Repoyum updates outbound ✓ · inbound new connection ✗ yum req packages attacker

The private server sends yum traffic to the NAT gateway (route 0.0.0.0/0 → nat-…). The NAT gateway in the public subnet uses its Elastic IP and the internet gateway, and the reply comes back. A new connection from the internet is refused.

The private instance sends traffic for the internet to its route table's 0.0.0.0/0 target: the NAT gateway. The NAT gateway replaces the private source address (10.0.2.10) with its own Elastic IP, sends the packet through the internet gateway, and passes the reply back. A connection started from the internet has nothing to match, so it is refused. That is why the NAT gateway itself must sit in a public subnet: it needs the IGW route.

How do I set up a NAT gateway step by step?

Step 1 — Create the NAT gateway in the public subnet

VPC → NAT gateways → Create NAT gateway:

Setting Value
Name society-nat
Availability mode (newer consoles) Zonal (the classic NAT gateway in one subnet; this guide uses it)
Subnet web-public-1a — a public subnet
Connectivity type Public
Elastic IP allocation ID Allocate Elastic IP

Create NAT gateway. The state goes from Pending to Available within a few minutes.

Step 2 — Point the private route table to it

Route tables → private-rt → Routes → Edit routes → Add route → Destination 0.0.0.0/0 → Target NAT Gateway → society-nat → Save changes. Make sure the private subnets are associated with private-rt.

Step 3 — Test from a private instance

SSH to the private instance through the bastion (how to) and run:

curl -s https://checkip.amazonaws.com
sudo yum update -y

The first command must print the NAT gateway's Elastic IP, not the instance's private IP.

Step 4 — Clean up after the lab

  1. VPC → NAT gateways → select society-nat → Actions → Delete NAT gateway → type delete → wait until Deleted.
  2. EC2 → Elastic IPs → select the address → Actions → Release Elastic IP addresses. Deleting the NAT gateway does not release it, and an idle public IPv4 address is billed too.
  3. The 0.0.0.0/0 route in private-rt now shows Blackhole; remove it or leave it for the next lab. 💸

Ravindra Bagale's Tip

The NAT gateway always goes in a public subnet – students create it in a private subnet and say "yum is not working, sir". The NAT itself needs the internet, so it must sit where the IGW route is. And in the private route table, the route goes to the NAT, not to the IGW. Two things – the NAT in public, the route from private.

Ravindra Bagale's Tip

My students' biggest AWS bills come from the NAT gateway. The lab is done, the laptop is closed, and the NAT runs for the whole month! When the lab ends, delete the NAT first, then release the Elastic IP – make that a rule. When you don't need it for practice, don't create a NAT at all.

How do I fix NAT gateway problems?

Ghabru naka 😅 — these are the usual ones:

Symptom Likely cause Fix
yum hangs, Curl error (28): Timeout was reached No 0.​0.​0.​0/​0 → nat-… route in the private route table, or wrong association Add the route; associate the private subnet with private-rt
NAT gateway state Failed Elastic IP quota reached, or the subnet had no free IP Release unused Elastic IPs; choose another subnet; create again
NAT is Available but still no internet NAT created in a private subnet (no IGW route there) Delete it and create it in the public subnet
Route shows Blackhole The NAT gateway was deleted Create a new NAT gateway and update the route
Custom NACL blocks the replies Private subnet NACL misses inbound 1024–65535 Add the ephemeral port rule
Bill still growing after deleting the NAT Elastic IP not released Release it in EC2 → Elastic IPs

Is a NAT gateway the only option?

For learning, you can avoid it: install packages while the instance is temporarily in a public subnet, or use VPC endpoints for AWS services such as Amazon S3 (a gateway endpoint for S3 has no hourly charge). A NAT instance (an EC2 you manage yourself) is cheaper but you patch and scale it yourself. For production private subnets, the managed NAT gateway, one per Availability Zone, is the standard choice.

Try it at home

Launch a private instance and run sudo yum install -y htop: it times out. Create the NAT gateway, add the route, run it again: it installs. Note the time you created the NAT, delete it within the hour, release the Elastic IP, and next day check that the bill shows only a small NAT gateway charge.

Got it? The NAT gateway goes in the public subnet with an Elastic IP, and the private route table has 0.0.0.0/0 → NAT. Going out works, coming in does not. After the lab, delete the NAT and release the Elastic IP – don't forget!

Frequently asked questions

Why does a NAT gateway need a public subnet?

The NAT gateway itself must reach the internet, so its subnet needs the route 0.0.0.0/0 to the internet gateway. The private subnets then route to the NAT gateway.

Does a NAT gateway allow inbound connections?

No. It only lets private instances start outbound connections and receive the replies. Connections started from the internet are refused.

How much does a NAT gateway cost?

It is charged for every hour it exists plus every GB of data it processes, and it is not in the free tier. Prices vary by Region; check the Amazon VPC pricing page and delete it after labs.

Does deleting a NAT gateway release the Elastic IP?

No. Release it separately in EC2, Elastic IPs; otherwise the idle public IPv4 address keeps being billed.

Why does yum still time out after creating a NAT gateway?

Usually the private route table has no 0.0.0.0/0 route to the NAT gateway, the subnet is associated with another route table, or the NAT gateway was created in a private subnet.

What is the difference between a NAT gateway and an internet gateway?

An internet gateway allows two-way traffic for instances with public IPs. A NAT gateway gives private instances outbound-only access using its own Elastic IP.