DEV Community

Cover image for Connecting Public and Private EC2 Instances to the Internet on AWS
Ruth kyalo
Ruth kyalo

Posted on

Connecting Public and Private EC2 Instances to the Internet on AWS

1. Introduction

When setting up AWS infrastructure, private EC2 instances don’t have direct internet access by design. However, they often need outbound connectivity for updates and patches. To enable this securely, AWS uses a networking model with public and private subnets, a NAT gateway or instance, and route tables. Public instances connect directly through an Internet Gateway (IGW), while private instances route traffic through a NAT in the public subnet. This blog explains how to design and connect both public and private EC2 instances to the internet step by step.

Prerequisites

Before getting started, make sure you have the following:

  • An AWS account with sufficient permissions (VPC, EC2, NAT Gateway, Internet Gateway).
  • An SSH client (e.g., PuTTY on Windows or terminal on macOS/Linux).

2. VPC Basics for Our Setup

Virtual Private Cloud (VPC)

A VPC is your isolated network inside AWS. When you create a VPC, you must specify an IPv4 CIDR block. Allowed block size ranges from /16 (65,536 IPs) to /28 (16 IPs).

Subnets

Subnets are smaller networks carved out of your VPC’s IP range.A subnet must be fully contained in one Availability Zone (AZ) — it cannot span across multiple AZs.

In every subnet, AWS reserves 5 IPs that cannot be used, if your subnet is 192.168.2.0/25 (128 IPs: .0–.127):

  • 192.168.2.0 → Network address (subnet identifier)
  • 192.168.2.1 → VPC router (always the first usable IP)
  • 192.168.2.2 → Reserved for Amazon DNS (if DNS is enabled in the VPC)
  • 192.168.2.3 → Reserved for future use
  • 192.168.2.127 → Broadcast address (reserved, not usable)

That leaves you with usable IPs from 192.168.2.4 to 192.168.2.126 → a total of 123 usable IPs.

Every subnet must be associated with a route table, which controls how traffic is forwarded.To calculate the subnets you are going to use, to can use this online-based subnet calculator

Public vs Private Subnets

Public Subnet A subnet whose route table has a route to an Internet Gateway (IGW).

  1. Use case: Resources that must be directly reachable from the internet.
  2. Examples: Bastion hosts, public-facing load balancers, or web servers.

Private Subnet A subnet without a direct route to the IGW. Instead, it may use a NAT Gateway/Instance for outbound-only internet access.

  1. Use case: Resources that should not be reachable from the internet, but still need outbound access.
  2. Examples: Application servers, databases, or internal services.

Route Tables

A route table is a set of rules that determine how network traffic is routed from your subnet.

Destination→ where the traffic is going.Example: 10.0.0.0/16 (local VPC traffic), 0.0.0.0/0 (all IPv4 internet traffic), ::/0 (all IPv6 traffic).

Target → the “next hop” that forwards the traffic.

  • Local (VPC internal routing)
  • Internet Gateway (IGW) → to the internet
  • NAT Gateway → for private subnet outbound internet
  • VPC Peering connection → to another VPC
  • VPN / Virtual Private Gateway (VGW) or Transit Gateway (TGW) → to on-prem

Gateways

Gateways connect your VPC to other networks.

  • Internet Gateway (IGW) → Allows public subnets to connect to the internet.
  • NAT Gateway or NAT Instance → Allows private subnets to reach the internet outbound only.
  1. NAT Instance: EC2 instance you manage yourself.
  2. NAT Gateway: Fully managed by AWS (preferred).Requires an Elastic IP (EIP) for outbound traffic. Must be launched in a public subnet (so it can reach the internet via IGW).NAT is stateful, meaning it keeps track of the state of active connections. If a device initiates a connection, the return traffic is automatically allowed, even if there’s no explicit inbound rule.

Elastic IP (EIP)

An Elastic IP is a static, public IPv4 address in AWS.EIPs can be associated with EC2 instances, network interfaces, or AWS resources.

Why it’s important:

  • Static Public Address → Doesn’t change when instances stop/start.
  • High Availability → Can be reassigned to another instance in the same region.
  • Required for NAT Gateway → NAT needs a stable outbound IP.
  • Firewall Whitelisting → External systems can safely whitelist your static

Security Controls

Security Groups (SGs) → Instance-level firewall.

Network ACLs (NACLs) → Subnet-level firewall.

3. Step-by-Step Setup

Step 1: Create the VPC, Subnets, and Internet Gateway

1. Create a VPC

  • Log in to your AWS Management Console.
  • Select a Region (e.g., us-east-1).
  • In the search bar at the top, type VPC and open the service.
  • Click Create VPC.
  • Choose VPC only.
  • Enter a name (e.g., MyDemoVPC).
  • Set the IPv4 CIDR block to 192.168.0.0/20.
  • Leave other options as default and click Create VPC.

2. Create Subnets

  • On your VPC dashboard select Subnets on the left menu and choose Create subnet.
  • Choose the VPC you just created.
  • Provide subnet name: public-subnet
  • Select an Availability Zone (e.g., us-east-1a).
  • IPv4 subnet CIDR block → 192.168.2.0/25

Click Add new subnet to add the private subnet:

  • Name: private-subnet
  • IPv4 subnet CIDR block → 192.168.2.128/25

  • Click Create subnet.

  • Go to the public subnet, select it → Actions → Edit subnet
    settings
    .

Editing subnet settings

  • Enable Auto-assign public IP and save.

3. Create and Attach an Internet Gateway (IGW)

  • In the VPC dashboard, go to Internet Gateways → Create internet gateway.
  • Enter a name (e.g., MyDemoIGW) and click Create.
  • Select the newly created IGW (it will show as detached) → Actions → Attach to VPC.
  • Choose your VPC (MyDemoVPC) and confirm.

4. Update Route Table for the Public Subnet

  • In the VPC dashboard, go to Route Tables.
  • Find the route table associated with your VPC (not the default route table).
  • Rename it (e.g., main-RT) and save.
  • On the Subnet Associations tab, confirm subnets explicitly associated.
  • On the Routes tab, click Edit routes

Editing routes

and add:

  • Destination: 0.0.0.0/0
  • Target: Internet Gateway (MyDemoIGW)

Save changes.

  • Go to Subnet associations → Edit subnet associations → Select your public subnet → Save.

Subnet Association


Step 2: Create a NAT Gateway for the Private Subnet

  1. Go to NAT Gateways in the VPC dashboard → Create NAT Gateway.
  2. Name it: MyDemoNATGateway.
  3. Place it in the public subnet.
  4. Connectivity type → Public.
  5. Allocate and attach an Elastic IP.
  6. Click Create NAT Gateway.

Step 3: Update Route Table for the Private Subnet

  • Go to Route Tables → Create route table.
  • Name it private-RT.
  • Select your VPC and create.
  • Under Subnet Associations → Edit subnet associations → Select private subnet → Save.
  • Under Routes → Edit routes → Add route:
    • Destination: 0.0.0.0/0
    • Target: NAT Gateway (MyDemoNATGateway)
  • Save changes.

Step 4: Create a Key Pair

  • Go to EC2 Dashboard → Key Pairs → Create key pair.
  • Name: mydemokey.
  • Private key format: .ppk (for PuTTY).

key creation

  • Create key pair (private key will be downloaded automatically).

Step 5: Launch EC2 Instances

Public EC2

  1. Go to EC2 Dashboard → Instances → Launch instance.
  2. Name: public-ec2.
  3. Instance type: t2.micro.
  4. Select your key pair (mydemokey).
  5. Network settings:
    • VPC: MyDemoVPC
    • Subnet: public-subnet
    • Enable auto-assign public IP.
  6. Firewall (security group): Security Groups
    • Name: public-sg
    • Inbound rule: SSH (source type: My IP).
  7. Leave other options as default
  8. Launch instance.

Private EC2

  1. Repeat the steps above.
  2. Name: private-ec2.
  3. Subnet: private-subnet.
  4. Disable auto-assign public IP.
  5. Firewall (security group):
    • Name: private-sg
    • Inbound rule: SSH (source Type: custom, source: public-sg).
  6. Launch instance.

SSH into Private EC2 via Public EC2

  1. Start Pageant

    • Search Pageant on your machine and open it. Once it’s opened, you’ll see it in the taskbar.
    • Right-click on it → Add Key → Select your private key.
    • Save the session so you don’t have to redo this step.
  2. Get EC2 Connection Details

    • In the AWS EC2 Dashboard → Select your public instance → Click Connect → Choose SSH Client.
    • You will see the username of the EC2 instance and its public IP.
    • Note both, since you will need them in the next step.
    • Repeat the same process for your private instance (make sure you select the correct instance to get its details).

instance username and Ip address

Configure PuTTY

  • Search for PuTTY on your machine.
  • Under Hostname, provide the public IP of your EC2 instance: public-ip.

configuring putty

Enable Agent Forwarding

  • Go to Connection → SSH → Auth → Tick Allow agent forwarding.
  • Click Open.

Enable Agent Forwarding

Connect to Public EC2

  • PuTTY will prompt you to enter the username (case-sensitive, usually ec2-user).

providing username

SSH from Public EC2 to Private EC2

  • From the public EC2, SSH into the private EC2 using:
   ssh ec2-user@<private-ip>
Enter fullscreen mode Exit fullscreen mode

Verify Login to Private EC2

  • After authentication, your terminal should display the username and private IP of the private EC2.

testing internet connection from private instance

  • Test internet connectivity from the private EC2:
   curl -I https://google.com
Enter fullscreen mode Exit fullscreen mode
  • You should get back the HTTP headers information.

Http headers


Understanding the Test

  • curl -I https://google.com is the correct way to test if your NAT Gateway works.

    • If you get headers back → outbound + return path are working.
    • curl → command-line tool for making network requests (HTTP, HTTPS, FTP, etc.).
    • -I (capital i) → fetches only the HTTP headers, not the full page body (faster, good for testing connectivity).
    • https://google.com → the URL you are requesting.

Breaking the NAT Gateway

To simulate failure:

  • In the AWS Console → Search for NAT Gateway → Select the NAT you want to delete → Actions → Delete.

Test again from the private EC2:

   curl -I https://google.com
Enter fullscreen mode Exit fullscreen mode

This time, it will fail to return headers, confirming that the NAT Gateway is required for private instances to access the internet.


Conclusion and Cleanup

In this blog, we walked through how to design a VPC with both public and private subnets, set up an Internet Gateway and NAT Gateway, launch EC2 instances, and securely connect to a private EC2 via a public bastion host. We also tested outbound connectivity and simulated NAT Gateway failure.

Important Reminder: Don’t forget to clean up your resources (EC2 instances, NAT Gateway, Elastic IP, and VPC) after testing to avoid unexpected AWS charges. NAT Gateways, in particular, can incur ongoing costs if left running.

Thanks for following along! 🚀

If you found this helpful, share it with others or drop your thoughts/questions in the comments.

Top comments (0)