# Where Are NAT Gateways Typically Placed in an AWS VPC? A Complete Placement Guide

> Discover where to place NAT gateways in your AWS VPC. Learn how public subnet placement enables secure outbound internet access for private instances.

- Repository: [Anil Kumar/DevOps-Interview-Guide](https://github.com/litu54/DevOps-Interview-Guide)
- Tags: how-to-guide
- Published: 2026-08-10

---

**NAT gateways are always provisioned in a public subnet** so that instances in private subnets can initiate outbound internet traffic while remaining protected from inbound connections.

The `litu54/DevOps-Interview-Guide` repository aggregates real-world DevOps interview questions from companies including Persistent Systems, Sigmoid, Capgemini, and Arrise Solutions, consistently highlighting that **where NAT gateways are placed within an AWS VPC** is a critical architectural concept tested during technical screenings. Understanding the distinction between public and private subnet placement is essential for designing secure, fault-tolerant network infrastructure on AWS.

## Why NAT Gateways Require Public Subnet Placement

A NAT gateway must be created in a **public subnet**—specifically, a subnet that has a route to an Internet Gateway (IGW). This placement is architectural, not optional. The NAT gateway itself needs direct internet connectivity to perform Network Address Translation for private instances.

As documented in [`Persistent_Systems/DevOps_Engineer_1.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Persistent_Systems/DevOps_Engineer_1.md), the interview question "Where does NATGateway reside" confirms this requirement. The file [`Sigmoid/DevOps_Engineer_4.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Sigmoid/DevOps_Engineer_4.md) reinforces this when discussing cluster requirements, noting that the NAT gateway's Elastic Network Interface (ENI) must reside in a subnet with IGW access.

## Route Table Configuration and Traffic Flow

The separation of concerns between public and private subnets is managed through route tables. While the NAT gateway physically exists in the public subnet, private subnets access it through specific routing entries.

### Public Subnet Routing

The public subnet hosting the NAT gateway must have a route table with a default route (`0.0.0.0/0`) pointing to the Internet Gateway. This allows the gateway to communicate with external destinations and receive return traffic.

### Private Subnet Routing

Private subnets do not contain routes to the IGW. Instead, their route tables direct internet-bound traffic (`0.0.0.0/0`) to the **NAT gateway ID**. This configuration, referenced in [`Arrise_Solutions/DevOps_Engineer.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Arrise_Solutions/DevOps_Engineer.md), ensures that instances without public IP addresses can reach the internet through the NAT gateway's public IP.

## High Availability and Multi-AZ Deployment

For production workloads, deploy one NAT gateway per Availability Zone (AZ). Each private subnet should route to the NAT gateway in the same AZ to eliminate single points of failure and avoid cross-AZ data transfer charges. If an AZ becomes unavailable, instances in other AZs retain internet connectivity through their local NAT gateway.

## Infrastructure as Code Examples

The following configurations demonstrate the correct placement of NAT gateways in public subnets using Terraform, AWS CLI, and CloudFormation.

### Terraform Configuration

This example from the repository analysis creates a NAT gateway in a public subnet and configures a private subnet to route through it:

```hcl
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}

# Public subnet (has route to IGW)

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.example.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-east-1a"
  map_public_ip_on_launch = true
}

# Private subnet (no direct IGW)

resource "aws_subnet" "private" {
  vpc_id            = aws_vpc.example.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "us-east-1a"
}

# Internet Gateway

resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.example.id
}

# Public route table (for public subnet)

resource "aws_route_table" "public_rt" {
  vpc_id = aws_vpc.example.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }
}
resource "aws_route_table_association" "public_assoc" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public_rt.id
}

# Elastic IP for NAT gateway

resource "aws_eip" "nat_eip" {
  vpc = true
}

# NAT Gateway in the public subnet

resource "aws_nat_gateway" "natgw" {
  allocation_id = aws_eip.nat_eip.id
  subnet_id     = aws_subnet.public.id
  depends_on    = [aws_internet_gateway.igw]
}

# Private route table (points to NAT)

resource "aws_route_table" "private_rt" {
  vpc_id = aws_vpc.example.id
  route {
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.natgw.id
  }
}
resource "aws_route_table_association" "private_assoc" {
  subnet_id      = aws_subnet.private.id
  route_table_id = aws_route_table.private_rt.id
}

```

### AWS CLI Verification

Verify the subnet placement using the AWS CLI:

```bash

# List NAT gateways

aws ec2 describe-nat-gateways

# Show details of a specific NAT gateway (replace <nat-gateway-id>)

aws ec2 describe-nat-gateways --nat-gateway-ids <nat-gateway-id> \
  --query "NatGateways[0].SubnetId" --output text

```

### CloudFormation Template

A minimal CloudFormation template placing the NAT gateway in a public subnet:

```yaml
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      AvailabilityZone: us-east-1a

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  PublicRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

  NatEIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatEIP.AllocationId
      SubnetId: !Ref PublicSubnet

```

## Cost and Security Considerations

Placing NAT gateways in public subnets optimizes both cost and security posture. NAT gateways incur hourly availability charges and data processing fees; routing through a public subnet avoids unnecessary cross-AZ transfer costs. From a security perspective, this architecture ensures private subnet instances remain unreachable from the internet while allowing outbound connections for updates and API calls, as detailed in [`Capgemini/DevOps_Engineer_3.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Capgemini/DevOps_Engineer_3.md) when contrasting NAT Gateways with Internet Gateways. The general definition and usage patterns are also documented in [`Others/DevOps_Engineer_15.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Others/DevOps_Engineer_15.md).

## Summary

- NAT gateways are provisioned exclusively in **public subnets** that have routes to an Internet Gateway.
- Private subnets access the internet by routing `0.0.0.0/0` traffic to the **NAT gateway ID**, not directly to an IGW.
- Deploy one NAT gateway per Availability Zone for high availability and to minimize data transfer costs.
- The `litu54/DevOps-Interview-Guide` repository confirms this placement pattern across multiple interview scenarios including [`Persistent_Systems/DevOps_Engineer_1.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Persistent_Systems/DevOps_Engineer_1.md) and [`Sigmoid/DevOps_Engineer_4.md`](https://github.com/litu54/DevOps-Interview-Guide/blob/main/Sigmoid/DevOps_Engineer_4.md).

## Frequently Asked Questions

### Can you place a NAT gateway in a private subnet?

No. A NAT gateway must reside in a public subnet with a route to an Internet Gateway. If placed in a private subnet without IGW access, the gateway would lack the necessary internet connectivity to translate addresses for outbound traffic, breaking the connection path for private instances.

### How many NAT gateways should I deploy?

Deploy one NAT gateway per Availability Zone that contains private subnets. This ensures fault tolerance if an AZ fails and prevents cross-AZ data transfer charges. Each private subnet should route to the NAT gateway located in its respective AZ.

### What is the difference between a NAT gateway and an Internet Gateway?

An Internet Gateway (IGW) enables bidirectional internet communication for resources with public IPs, while a NAT gateway allows only **outbound** internet access for resources in private subnets. The NAT gateway requires an IGW in its public subnet to function, but private instances never communicate directly with the IGW.

### Do NAT gateways require Elastic IPs?

Yes. NAT gateways require an Elastic IP address (EIP) for static public IP addressing. This EIP is associated with the gateway's ENI in the public subnet, allowing return traffic from the internet to reach the gateway consistently without dynamic IP changes.