In my previous tutorial, we built a custom VPC with public and private subnets, an Internet Gateway, and an EC2 instance running in the public subnet.
While the private subnet was secure, it had one major limitationβit couldn't access the internet at all.
In real-world AWS environments, private resources such as application servers and databases often need outbound internet access to install updates, download packages, or communicate with external APIs, while remaining inaccessible from the public internet.
This is exactly where a NAT Gateway comes in.
By the end of this guide, you'll configure a NAT Gateway that allows instances in a private subnet to securely access the internet without exposing them to inbound traffic.
π What You'll Build
In this tutorial, we'll create:
- β An Elastic IP
- β A NAT Gateway
- β Updated Private Route Table
- β A Private EC2 Instance
- β Secure outbound internet connectivity for the private subnet
π§ What is a NAT Gateway?
A Network Address Translation (NAT) Gateway enables instances in a private subnet to initiate outbound connections to the internet while preventing inbound connections initiated from the internet.
Think of it like a one-way door:
- β Private Subnet β Internet
- β Internet β Private Subnet
This allows servers to download software updates, install packages, or communicate with external services without exposing them to public access.
ποΈ Architecture
π Prerequisites
Before continuing, ensure you already have:
- A custom VPC (
demo-vpc) - A Public Subnet (
demo-public-subnet-1a) - A Private Subnet (
demo-private-subnet-1a) - An Internet Gateway attached to the VPC
- A Route Table for each subnet
- An EC2 instance running in the public subnet
If you haven't completed those steps, check out my previous article on building a custom VPC.
Step 1 β Allocate an Elastic IP
A NAT Gateway requires a static public IP address.
Navigate to:
VPC β Elastic IPs β Allocate Elastic IP Address
Leave the default settings and click Allocate.
Give it a name such as:
demo-natgw-eip
Step 2 β Create the NAT Gateway
Navigate to:
VPC β NAT Gateways β Create NAT Gateway
Use the following configuration.
| Setting | Value |
|---|---|
| Name | demo-NATGW |
| Subnet | demo-public-subnet-1a |
| Connectivity Type | Public |
| Elastic IP | demo-natgw-eip |
Click Create NAT Gateway.
It usually takes a couple of minutes before its status changes to Available.
β οΈ Important
A NAT Gateway must always be deployed in a public subnet so it can communicate with the Internet Gateway.
Step 3 β Update the Private Route Table
Now we'll allow the private subnet to send outbound traffic through the NAT Gateway.
Navigate to:
VPC β Route Tables β demo-private-RT
Edit the routes and configure:
| Destination | Target |
|---|---|
| 10.0.0.0/16 | local |
| 0.0.0.0/0 | demo-NATGW |
Save the changes.
Your private subnet can now initiate outbound internet connections while remaining inaccessible from the internet.
Step 4 β Launch an EC2 Instance in the Private Subnet
Launch another EC2 instance using the following configuration.
| Setting | Value |
|---|---|
| AMI | Amazon Linux 2 |
| Instance Type | t3.micro |
| VPC | demo-vpc |
| Subnet | demo-private-subnet-1a |
| Auto Assign Public IP | Disabled |
For the Security Group:
- Allow SSH (22) only from the public EC2 instance or Bastion Host
- Do not allow SSH from
0.0.0.0/0
Launch the instance.
Notice that the instance has no Public IPv4 address, which means it cannot be accessed directly from the internet.
Step 5 β Verify NAT Gateway Connectivity
Since the private instance doesn't have a public IP, we'll first connect to the public EC2 instance and then access the private instance from there.
5.1 Copy the Key Pair
From your local machine:
scp -i demo_ec2.pem demo_ec2.pem ec2-user@<public-instance-ip>:~/
π‘ Tip
In production environments, SSH Agent Forwarding is preferred instead of copying private keys.
5.2 Connect to the Public EC2
ssh -i demo_ec2.pem ec2-user@<public-instance-ip>
5.3 Connect to the Private EC2
chmod 400 demo_ec2.pem
ssh -i demo_ec2.pem ec2-user@<private-instance-private-ip>
5.4 Test Internet Access
Run the following commands from the private EC2 instance.
ping 8.8.8.8
If everything is configured correctly, you'll receive a response similar to:
Pinging 8.8.8.8 with 32 bytes of data:
Reply from 8.8.8.8: bytes=32 time=60ms TTL=117
Reply from 8.8.8.8: bytes=32 time=47ms TTL=117
This confirms that:
- β The instance has internet access.
- β Traffic is passing through the NAT Gateway.
- β The instance still has no public IP.
5.5 Verify the Instance is Still Private
Try connecting directly to the private instance from your laptop.
ssh ec2-user@<private-instance-private-ip>
The connection should fail because the instance remains isolated from inbound internet traffic.
This is exactly how private application servers and databases are deployed in production environments.
π Quick Recap
| Resource | Purpose |
|---|---|
| demo-natgw-eip | Static Public IP |
| demo-NATGW | Provides outbound internet access |
| demo-private-RT | Routes traffic through the NAT Gateway |
| Private EC2 | Secure instance without a Public IP |
π° Cost Note
β οΈ NAT Gateways are not included in the AWS Free Tier.
AWS charges:
- Hourly usage
- Data processing per GB
For learning purposes, remember to delete the NAT Gateway and release the Elastic IP when you're finished to avoid unnecessary charges.
π§Ή Cleanup
Once you're done experimenting:
- Terminate both EC2 instances.
- Delete the NAT Gateway.
- Release the Elastic IP.
- Remove the
0.0.0.0/0 β demo-NATGWroute from the private Route Table. - (Optional) Delete the subnets, Internet Gateway, and VPC.
π Conclusion
Congratulations! You've successfully extended your custom AWS VPC by adding a NAT Gateway.
In this tutorial, you learned how to:
- Allocate an Elastic IP
- Deploy a NAT Gateway
- Configure a Private Route Table
- Launch a private EC2 instance
- Enable outbound-only internet access
- Maintain secure network isolation
This architecture is widely used in production AWS environments because it balances security and connectivity. Public-facing services remain accessible, while backend systems can safely communicate with the internet without being directly exposed.
π What's Next?
In the next project, we'll explore how to make this architecture even more resilient by introducing services such as:
- Application Load Balancer (ALB)
- Auto Scaling Groups
- Multi-AZ deployments
- Amazon RDS in a private subnet
Together, these components form the foundation of highly available and production-ready AWS architectures.
Happy Cloud Learning! βοΈπ
Source Code & Project Files
The complete project, including all three stagesβ
- Amazon EC2 Deployment
- Custom VPC with Public & Private Subnets
- NAT Gateway Configuration
βis available on my GitHub repository.

Top comments (0)