AWS - Accessing instances in private subnet using EIP
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
An Elastic IP is a public IPv4 address, but attaching one does not magically turn a private-subnet instance into a public one. In AWS, reachability depends on the whole network path: subnet routing, internet gateway access, security groups, and the access pattern you actually need.
Why An Elastic IP Is Not Enough
People often ask whether they can keep an EC2 instance in a private subnet and still reach it directly by assigning an Elastic IP. The answer is no for the usual private-subnet design. A private subnet does not have a route that makes the instance directly reachable from the internet through an internet gateway.
An Elastic IP is only one piece of addressing. Reachability also needs a public routing path. Without that path, inbound internet traffic still cannot land on the instance the way it can for an instance in a public subnet.
That is why the normal design is not "private instance plus EIP." It is "private instance plus a controlled access path."
Choose The Access Pattern First
The right answer depends on the reason you need access:
- for administrative shell access, use Session Manager or a bastion host
- for user traffic to an app, use a load balancer
- for outbound internet access from the instance, use a NAT gateway or VPC endpoints
These are different problems, and confusing them leads to awkward VPC designs.
Bastion Host Pattern
The traditional SSH pattern is a bastion host in a public subnet. That bastion can have a public IP or Elastic IP, while the application instances stay private.
The network model usually looks like this:
- public subnet has a route to the internet gateway
- bastion host has the EIP
- private subnet allows internal traffic from the bastion
- private instance has no public address
Security groups are typically scoped so only the bastion can reach port 22 on the private instance. That preserves the private-subnet boundary while still giving operators a controlled entry point.
Session Manager Is Usually Better
AWS Systems Manager Session Manager is often a cleaner option because it avoids inbound SSH entirely. According to AWS documentation, Session Manager can connect to managed instances without opening inbound ports or assigning public IP addresses.
Typical requirements include:
- SSM agent on the instance
- IAM role permitting SSM access
- a network path to Systems Manager endpoints, either through NAT or interface VPC endpoints
Once configured, you can start a session without any public address on the instance:
For operational access, this is usually better than maintaining bastions, SSH key distribution, and open port 22 rules.
Load Balancers For Application Traffic
If the goal is to expose a service, put the private instances behind a public Application Load Balancer or Network Load Balancer:
This is the standard way to publish a web application while keeping the compute layer unreachable from the public internet.
NAT Gateway Solves A Different Problem
A NAT gateway is often involved in private-subnet discussions, but it only solves outbound connectivity. It lets private instances reach package repositories, AWS APIs, or external services without becoming directly reachable from the internet.
It is not a reverse tunnel for inbound administrative access. If the instance needs inbound access from operators or end users, that path must be provided separately.
A Minimal Bastion Example
Here is a small security-group sketch for a bastion design:
- bastion security group allows inbound TCP 22 from your office IP or VPN range
- private instance security group allows inbound TCP 22 only from the bastion security group
This keeps the private instance unreachable from arbitrary public clients even though an approved operator can still reach it through the bastion path.
What To Do In Practice
If you are choosing today, a sensible default is:
- Keep the workload instance in a private subnet.
- Use Session Manager for operator access if your environment allows it.
- Use a public load balancer for user-facing HTTP or TCP traffic.
- Use NAT or VPC endpoints only for outbound dependencies.
That model maps cleanly onto AWS networking and is easier to secure than trying to bend Elastic IPs into a role they were not designed to fill.
Common Pitfalls
- Assuming an Elastic IP alone makes a private-subnet instance directly reachable from the internet.
- Using a NAT gateway as though it handles inbound access.
- Moving a workload into a public subnet just to make SSH simpler.
- Opening SSH broadly to the internet when Session Manager or a tightly scoped bastion would be safer.
- Using a bastion for user-facing application traffic instead of putting a load balancer in front of private targets.
Summary
- An Elastic IP does not override private-subnet routing rules.
- For administrative access, prefer Session Manager or use a bastion host.
- For application traffic, put a public load balancer in front of private instances.
- NAT gateways are for outbound access, not inbound reachability.
- The safest design keeps the instance private and adds an explicit, controlled access path.

