NAT Gateways & Bastion Hosts
Key concepts
NAT Gateway for outbound internet
NAT Gateway is highly available per AZ
Bastion hosts for SSH/RDP access
Session Manager as bastion alternative
NAT instance vs NAT Gateway
Overview
NAT Gateways and Bastion Hosts solve two different but related problems in VPC security. NAT Gateways enable instances in private subnets to access the internet for outbound traffic (like downloading updates) without being directly accessible from the internet. Bastion Hosts (jump boxes) provide secure inbound administrative access to instances in private subnets.
Understanding the difference between these services - and when to use each - is essential for the SAA-C03 exam. A common exam pattern presents scenarios where you must choose between NAT Gateway, NAT Instance, and Bastion Host based on the traffic direction and use case.
Key Distinction
NAT Gateway: Enables OUTBOUND internet access from private subnets Bastion Host: Enables INBOUND administrative access to private subnets
They solve opposite problems - NAT is for going OUT, Bastion is for coming IN.
If a question mentions 'instances in private subnets need to download patches from the internet,' the answer is NAT Gateway. If it mentions 'administrators need to SSH into private instances,' think Bastion Host or Session Manager.
Architecture Diagram

Key Concepts
NAT Gateway
NAT Gateway
NAT Gateway is a managed service that enables outbound internet connectivity for private subnet resources.
Key Characteristics:
- Managed service: No maintenance required
- Highly available: Within a single AZ
- Scalable: Up to 45 Gbps bandwidth
- Elastic IP required: Static public IP
- Charged hourly + data processed
How It Works:
- Private instance sends traffic to NAT Gateway
- NAT Gateway translates source IP to its Elastic IP
- Traffic goes to internet via Internet Gateway
- Response returns to NAT Gateway
- NAT Gateway forwards response to private instance
NAT Instance (Legacy)
NAT Instance
NAT Instance is an EC2 instance configured to perform NAT. Largely replaced by NAT Gateway but still appears on exams.
Key Characteristics:
- Self-managed: You manage patching, scaling, HA
- EC2 pricing: Can be cheaper for low traffic
- Security groups: More control over traffic
- Can be bastion: Dual purpose possible
- Source/dest check: Must be DISABLED
When to Consider:
- Very low traffic (cost savings)
- Need port forwarding
- Need bastion + NAT combined
- Educational/testing purposes
NAT Gateway vs NAT Instance
NAT Gateway vs NAT Instance
| Feature | NAT Gateway | NAT Instance |
|---|---|---|
| Availability | Highly available in AZ | Use script/ASG for HA |
| Bandwidth | Up to 45 Gbps | Depends on instance type |
| Maintenance | Managed by AWS | You manage |
| Cost | Hourly + data | EC2 instance cost |
| Security Groups | No (use NACLs) | Yes |
| Bastion Use | No | Yes (can dual-purpose) |
| Source/Dest Check | N/A | Must disable |
| Public IP | Elastic IP | Elastic IP or public IP |
| Recommended | Yes (most cases) | Legacy/special cases |
Bastion Host
Bastion Host (Jump Box)
Bastion Host is a hardened EC2 instance in a public subnet used to access private instances.
Key Characteristics:
- Public subnet: Has public IP or Elastic IP
- Hardened OS: Minimal software, security updates
- Restricted access: Only allow SSH/RDP from known IPs
- Audit logging: Track all access
- Single purpose: Only for administrative access
Security Best Practices:
- Restrict SSH to specific IP ranges (your office)
- Use key-based authentication only
- Enable session logging (CloudWatch)
- Use SSH agent forwarding (don't store keys on bastion)
- Consider using AWS Systems Manager Session Manager instead
AWS Systems Manager Session Manager
Session Manager (Modern Alternative)
Session Manager is a fully managed service that provides shell access without opening inbound ports.
Advantages over Bastion:
- No bastion host to manage
- No SSH keys to manage
- No inbound ports (22/3389) needed
- Audit logging built-in (CloudTrail)
- IAM-based access control
- Works through NAT Gateway
Requirements:
- SSM Agent on instances (pre-installed on many AMIs)
- IAM role with SSM permissions
- VPC endpoint OR NAT Gateway for private instances
Bastion Host vs Session Manager
| Feature | Bastion Host | Session Manager |
|---|---|---|
| Infrastructure | EC2 instance to manage | No infrastructure |
| Inbound Ports | SSH (22) or RDP (3389) | None required |
| Keys/Credentials | SSH keys or passwords | IAM only |
| Audit Trail | Manual setup | Built-in (CloudTrail) |
| Cost | EC2 instance cost | Free (pay for data) |
| Multi-AZ | Deploy in each AZ | Automatic |
| Recommendation | Legacy/specific needs | Preferred for most |
How It Works
NAT Gateway Setup
# Allocate Elastic IP for NAT Gateway
aws ec2 allocate-address --domain vpc
# Create NAT Gateway in public subnet
aws ec2 create-nat-gateway \
--subnet-id subnet-public-1a \
--allocation-id eipalloc-xxx \
--tag-specifications 'ResourceType=natgateway,Tags=[{Key=Name,Value=NAT-1a}]'
# Wait for NAT Gateway to be available
aws ec2 wait nat-gateway-available --nat-gateway-ids nat-xxx
# Add route in private subnet route table
aws ec2 create-route \
--route-table-id rtb-private \
--destination-cidr-block 0.0.0.0/0 \
--nat-gateway-id nat-xxxHigh Availability NAT Setup
For production, deploy NAT Gateway in each AZ:

AZ-1a:
Public Subnet: NAT-Gateway-1a (EIP-1)
Private Subnet Route: 0.0.0.0/0 → NAT-Gateway-1a
AZ-1b:
Public Subnet: NAT-Gateway-1b (EIP-2)
Private Subnet Route: 0.0.0.0/0 → NAT-Gateway-1b
AZ-1c:
Public Subnet: NAT-Gateway-1c (EIP-3)
Private Subnet Route: 0.0.0.0/0 → NAT-Gateway-1c
This ensures that if one AZ fails, instances in other AZs
still have internet access through their local NAT Gateway.Bastion Host Setup
# Create security group for bastion
aws ec2 create-security-group \
--group-name Bastion-SG \
--description "Security group for bastion host" \
--vpc-id vpc-xxx
# Allow SSH only from your IP
aws ec2 authorize-security-group-ingress \
--group-id sg-bastion \
--protocol tcp \
--port 22 \
--cidr YOUR.IP.ADDRESS/32
# Launch bastion instance
aws ec2 run-instances \
--image-id ami-xxx \
--instance-type t3.micro \
--key-name my-key \
--subnet-id subnet-public-1a \
--security-group-ids sg-bastion \
--associate-public-ip-address \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=Bastion}]'SSH Agent Forwarding
# On your local machine - add key to SSH agent
ssh-add ~/.ssh/my-private-key.pem
# Connect to bastion with agent forwarding (-A flag)
ssh -A ec2-user@bastion-public-ip
# From bastion, connect to private instance
# (uses forwarded key, no key stored on bastion)
ssh ec2-user@private-instance-ipSession Manager Setup
# IAM role policy for EC2 to use Session Manager
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:UpdateInstanceInformation",
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
}
]
}
# Start session from CLI
aws ssm start-session --target i-xxx
# Or use AWS Console: EC2 → Instance → Connect → Session ManagerUse Cases
Use Case 1: Private Instances Need Software Updates
Scenario: EC2 instances in private subnets need to download OS patches and application updates.

Solution:
- Deploy NAT Gateway in public subnet
- Route 0.0.0.0/0 from private subnet to NAT Gateway
- Instances use NAT Gateway for outbound internet
Use Case 2: Administrators Need SSH Access
Scenario: DevOps team needs to SSH into private EC2 instances for troubleshooting.

Solution (Modern):
- Install SSM Agent on instances
- Attach IAM role with SSM permissions
- Use Session Manager for access

Solution (Traditional):
- Deploy bastion host in public subnet
- Restrict SSH to corporate IP range
- Use SSH agent forwarding
Use Case 3: Consistent Outbound IP for Whitelisting
Scenario: Third-party API requires whitelisting your IP address.
Solution:
- NAT Gateway provides consistent Elastic IP
- All private subnet traffic appears from NAT Gateway's EIP
- Whitelist the EIP with the third party
Use Case 4: Cost-Optimized NAT for Dev/Test
Scenario: Development environment with minimal traffic needs NAT but cost is a concern.
Solution:
- Consider NAT Instance (t3.micro)
- Accept trade-off of managing the instance
- Or accept single-AZ NAT Gateway for lower cost
Best Practices
NAT Gateway Best Practices
- Deploy in Each AZ - One NAT Gateway per AZ for high availability
- Monitor Data Processing - NAT Gateway charges per GB processed
- Use VPC Endpoints - Reduce NAT costs for AWS service traffic (S3, DynamoDB)
- Size Route Tables Correctly - Each private subnet routes to its AZ's NAT Gateway
- Set Up Alarms - Monitor bandwidth and connection counts
- Consider NAT Gateway Pricing - $0.045/hour + $0.045/GB (varies by region)
Bastion Host Best Practices
- Consider Session Manager First - No infrastructure to manage
- Restrict Source IPs - Only allow known IP ranges
- Use SSH Agent Forwarding - Never store private keys on bastion
- Enable Logging - CloudWatch Logs for session recording
- Harden the OS - Minimal software, regular patching
- Single Purpose - Don't use bastion for other workloads
- Multi-AZ - Deploy bastion in each AZ if needed
Common Exam Scenarios
Exam Scenarios
| Scenario | Solution | Why |
|---|---|---|
| Private instances need internet for updates | NAT Gateway | Enables outbound internet from private subnet |
| Admins need SSH to private instances | Bastion Host or Session Manager | Enables inbound administrative access |
| Need HA for NAT across AZs | NAT Gateway in each AZ | NAT Gateway is HA within AZ only |
| Third-party needs to whitelist your IP | NAT Gateway (Elastic IP) | Consistent outbound IP address |
| Reduce NAT costs for S3 access | S3 Gateway Endpoint | Traffic does not go through NAT |
| Need both NAT and bastion, minimize cost | NAT Instance | Can serve dual purpose |
| Secure access without SSH keys | Session Manager | IAM-based, no keys needed |
| Bastion should not store credentials | SSH Agent Forwarding | Keys never leave local machine |
Common Pitfalls
Pitfall 1: Single AZ NAT Gateway
Mistake: Deploying only one NAT Gateway for all private subnets.
Why it's risky:
- NAT Gateway is HA within AZ only
- If that AZ fails, all private subnets lose internet
- Cross-AZ data charges apply
Correct Approach:
- Deploy NAT Gateway in each AZ
- Route each private subnet to its local NAT Gateway
- Accept higher cost for high availability
Pitfall 2: Storing SSH Keys on Bastion
Mistake: Copying private keys to the bastion host.
Why it's dangerous:
- If bastion is compromised, all keys are exposed
- Violates security best practices
- Key management nightmare
Correct Approach:
- Use SSH agent forwarding
- Or use Session Manager (no keys at all)
- Never store private keys on bastion
Pitfall 3: Open SSH to 0.0.0.0/0
Mistake: Allowing SSH from any IP address to bastion.
Why it's dangerous:
- Exposed to brute force attacks
- Increases attack surface
- Compliance violations
Correct Approach:
- Restrict to known IP ranges (corporate network)
- Use VPN for remote access
- Better yet, use Session Manager
Pitfall 4: NAT Gateway for AWS Service Access
Mistake: Routing S3/DynamoDB traffic through NAT Gateway.
Why it's wasteful:
- NAT Gateway charges $0.045/GB
- S3/DynamoDB are in the same region
- Unnecessary cost and latency
Correct Approach:
- Use VPC Gateway Endpoints for S3 and DynamoDB
- Free and keeps traffic within AWS network
- Only use NAT for actual internet destinations
Test Your Knowledge
What is the primary purpose of a NAT Gateway?
A company needs high availability for NAT across three AZs. What is the recommended setup?
Which solution provides SSH access to private instances WITHOUT managing SSH keys?
A NAT Instance is not working. What setting must be checked?
Related Services
Quick Reference
NAT Gateway Pricing (Example: us-east-1)
NAT Gateway Costs
| Component | Cost |
|---|---|
| Hourly charge | $0.045/hour (~$32/month) |
| Data processing | $0.045/GB |
| Example: 100GB/month | $32 + $4.50 = $36.50/month |
| Multi-AZ (3 NAT GWs) | ~$100/month + data |
NAT Gateway Limits
NAT Gateway Limits
| Limit | Value |
|---|---|
| Bandwidth | Up to 45 Gbps |
| Packets per second | Up to 4 million |
| Connections per second | 55,000 |
| Concurrent connections | Up to 350,000 |
| NAT Gateways per AZ | 5 (can increase) |
CLI Commands Reference
# List NAT Gateways
aws ec2 describe-nat-gateways --filter "Name=vpc-id,Values=vpc-xxx"
# Delete NAT Gateway
aws ec2 delete-nat-gateway --nat-gateway-id nat-xxx
# Release Elastic IP (after NAT Gateway deleted)
aws ec2 release-address --allocation-id eipalloc-xxx
# Start Session Manager session
aws ssm start-session --target i-xxx
# Describe instances with SSM agent
aws ssm describe-instance-information
# Get Session Manager connection log
aws ssm describe-sessions --state Active