AWS Day 30: Enable Internet Access for Private EC2 using NAT Instance

"I'm a 3rd-year Computer Engineering student at Marwadi University with skills in C++, web development (MERN stack), and DevOps tools like Kubernetes. I contribute to open-source projects and share tech knowledge on GitHub and LinkedIn. I'm learning cloud technologies and app deployment. As an Internshala Student Partner, I help others find jobs and courses." now currently focusing on #90DaysOfDevops
Introduction
During Day 30 of the KodeKloud 100 Days of Cloud Challenge, I worked on one of the most interesting AWS networking concepts: providing internet access to a private EC2 instance using a NAT Instance.
In a well-designed AWS architecture, application servers are often deployed inside private subnets to improve security. Since these instances don't have public IP addresses, they cannot directly access the internet for tasks such as downloading software updates or communicating with AWS services.
To solve this problem, AWS provides two common solutions: NAT Gateway and NAT Instance. While NAT Gateway is the recommended managed service, this lab focused on configuring a NAT Instance, which is a cost-effective option for learning and small environments.
Why Use a NAT Instance?
A NAT (Network Address Translation) Instance allows EC2 instances in a private subnet to initiate outbound internet connections while preventing inbound connections directly from the internet.
Common use cases include:
Downloading software packages
Installing application dependencies
Accessing Amazon S3
Retrieving updates from public repositories
Secure outbound internet connectivity
Although AWS recommends using a NAT Gateway for production workloads, understanding how a NAT Instance works provides valuable insight into AWS networking.
Task Requirements
The objective of this lab was to:
Create a public subnet named nautilus-pub-subnet
Launch an Amazon Linux 2023 EC2 instance named nautilus-nat-instance
Configure the instance to function as a NAT Instance
Create and attach a custom Security Group
Enable internet access for the existing private EC2 instance
Verify that the file nautilus-test.txt was uploaded successfully to the S3 bucket nautilus-nat-32360
Step 1: Create a Public Subnet
I opened the VPC Console and created a new public subnet inside the existing nautilus-priv-vpc.
The subnet was configured with the following details:
| Setting | Value |
|---|---|
| Name | nautilus-pub-subnet |
| VPC | nautilus-priv-vpc |
To make the subnet public, I associated it with a route table that routes internet-bound traffic through the Internet Gateway.
Step 2: Attach an Internet Gateway to the VPC
After creating the public subnet, I created a new Internet Gateway and attached it to the existing nautilus-priv-vpc. This allows resources inside the public subnet to communicate with the internet.
Navigation:
VPC → Internet Gateways → Create Internet Gateway → Attach to VPC
Once attached, the Internet Gateway status changed to Attached, confirming that the VPC now had internet connectivity.
Step 3: Update the Public Route Table
Next, I modified the route table associated with the public subnet.
I added a new route so that all outbound internet traffic is forwarded through the Internet Gateway.
| Destination | Target |
|---|---|
| 0.0.0.0/0 | Internet Gateway (pub-ig) |
Without this route, instances in the public subnet would not be able to reach the internet.
Step 4: Launch the NAT Instance
Now I launched an EC2 instance that will act as the NAT Instance.
The configuration used was:
| Setting | Value |
|---|---|
| Name | nautilus-nat-instance |
| AMI | Amazon Linux 2023 |
| VPC | nautilus-priv-vpc |
| Subnet | nautilus-pub-subnet |
| Auto Assign Public IP | Enabled |
| Security Group | New Security Group |
The NAT Instance was launched inside the newly created public subnet so it could communicate with both the internet and the private subnet.
Step 5: Disable Source/Destination Check
By default, every EC2 instance validates that network traffic is either coming from or intended for itself.
Since a NAT Instance forwards traffic on behalf of other EC2 instances, this feature must be disabled.
I selected the NAT instance and navigated to:
Actions → Networking → Change Source/Destination Check
Then I disabled Source/Destination Check.
This is one of the most important steps while configuring a NAT Instance.
Step 6: Configure the NAT Instance Security Group
To allow internet traffic to pass through the NAT Instance, I updated its Security Group.
The inbound rules included:
SSH (22) – for remote administration
HTTP (80) – to allow outbound web traffic
HTTPS (443) – for secure internet access
Custom ICMP – for connectivity testing
This ensures that the NAT Instance can communicate properly with both the internet and the private subnet.
Step 7: Configure the NAT Instance
After connecting to the NAT Instance through SSH, I installed iptables, enabled IP forwarding, and configured NAT rules.
# 1. Install iptables
sudo yum install -y iptables-services
# 2. Enable IP forwarding
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 3. Find the network interface
ip addr
# 4. Add NAT rule (replace ens5 with your interface)
sudo iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE
# 5. Allow forwarding
sudo iptables -P FORWARD ACCEPT
sudo iptables -A FORWARD -i ens5 -j ACCEPT
sudo iptables -A FORWARD -o ens5 -j ACCEPT
# 6. Enable and save iptables
sudo systemctl enable iptables
sudo systemctl start iptables
sudo service iptables save
Step 8: Update the Private Route Table
Finally, I updated the route table associated with the private subnet.
Instead of routing internet traffic directly to an Internet Gateway, I pointed the default route to the NAT Instance.
| Destination | Target |
|---|---|
| 0.0.0.0/0 | nautilus-nat-instance |
Now, whenever the private EC2 instance needs internet access, its traffic is first forwarded to the NAT Instance, which then sends it to the internet.
Step 9: Verify Internet Connectivity
To verify the setup, I checked the Amazon S3 bucket.
The private EC2 instance was already configured with a cron job that attempted to upload a test file every minute.
After the NAT Instance was configured successfully, the file nautilus-test.txt appeared inside the S3 bucket, confirming that the private EC2 instance could now access the internet through the NAT Instance.
What I Learned
This lab helped me understand how outbound internet access works for resources deployed in private subnets.
One important lesson was that launching a NAT Instance alone is not enough. Several configurations—including disabling Source/Destination Check, enabling IP forwarding, configuring iptables, and updating the route table—must all work together before traffic can flow successfully.
I also learned why managed NAT Gateways are preferred in production environments, while NAT Instances remain a useful option for learning, testing, and cost-sensitive deployments.
Conclusion
Day 30 introduced one of the most important networking concepts in AWS by enabling internet access for a private EC2 instance using a NAT Instance.
By creating a public subnet, configuring a NAT Instance, updating route tables, and verifying connectivity through an S3 upload, I gained practical experience with how private workloads securely access external services without being directly exposed to the internet.




