Zin Moe / Projects← All projects
AWS · Terraform · Session Manager

Private EC2 access through a NAT Gateway

This lab uses an Internet Gateway and a NAT Gateway to let three private EC2 instances reach AWS Systems Manager public endpoints. Operators connect through Session Manager; the instances have no public IPs or inbound SSH rule.

3Private EC2 instances
1Public subnet
1NAT Gateway
0SSM VPC endpoints

Architecture

The VPC is 10.0.0.0/16 in ap-southeast-1. Its public subnet routes to an Internet Gateway and hosts the NAT Gateway. Three private subnets each have a default route to that NAT Gateway. The EC2 instance profile grants Systems Manager permissions, and the instance security group permits outbound TCP 443.

Repository diagram showing three private EC2 instances, IAM instance profile, NAT Gateway, Internet Gateway and Session Manager connection
Architecture diagram from the repository. Select to open at full size.

Implementation

  1. Create the VPC

    Enable DNS support and hostnames in the VPC. Place one public subnet and three private subnets in the selected availability zones.

  2. Route outbound traffic

    Attach an Internet Gateway. Put a NAT Gateway with an Elastic IP in the public subnet, and route each private subnet's 0.0.0.0/0 traffic to it.

  3. Launch the instances

    Use an Ubuntu 24.04 AMI for three EC2 instances, one per private subnet. Explicitly disable public IP assignment on every instance.

  4. Grant SSM permissions

    Attach AmazonSSMManagedInstanceCore to the EC2 IAM role and associate its instance profile with the instances.

  5. Allow HTTPS egress

    Configure the instance security group for outbound TCP 443. The Terraform does not define an inbound SSH rule or any SSM interface endpoint.

  6. Open a session

    With the AWS CLI and Session Manager plugin on the operator's machine, start a session against the managed instance ID.

Lab verification

The repository README records a successful Session Manager shell on a private instance. It shows a private 10.0.50.19 address and an HTTPS response from an external site, demonstrating the lab's outbound path at the time of the test.

aws ssm start-session --target <instance-id> --profile <your-profile>

The instance ID in the README is a recorded example. Use an ID from your own deployment when reproducing this lab.

Design tradeoff

Compared with the VPC endpoint version, this design sends outbound service traffic through a NAT Gateway. The Terraform creates a single NAT Gateway in the public subnet and routes all three private subnets through it. For a production design, evaluate its availability, traffic path, and ongoing NAT charges.

Based on the aws_ssm_without_vpc_endpoints folder on GitLab. The page describes the repository and its recorded lab result, not a continuously running environment.