AWS – Setting up NAT gateways

Initial Configurations of Windows server 2019

Unless required, your instances should not be publicly exposed to the internet. When your instances are on the internet, you have to assume they will be attacked at some stage.

This means most of your workloads should run on instances in private subnets. Private subnets are those that are not connected directly to the internet.

To give your private instances access to the internet, you use NAT. A NAT gateway allows your instances to initiate a connection to the internet, without allowing connections from the internet.

Getting ready

For this recipe, you must have the following existing resources:

  • A VPC with an IGW
  • A public subnet
  • A private subnet route table

You will need the IDs for the public subnet and private subnet route table. Both of these resources should be in the same AZ.

How to do it…

In this recipe, you will create a new CloudFormation that creates a stack with a NAT gateway. Let’s get started:

  1. Start with the usual CloudFormation template version and description:
AWSTemplateFormatVersion: "2010-09-09" 
Description: Create NAT Gateway and associated route.
  1. The template must take the following required parameters:
    Description: Public Subnet ID to add the NAT Gateway to 
    Type: AWS::EC2::Subnet::Id 
    Description: The private subnet route table to add the NAT
    Gateway route to 
    Type: String
  1. In the Resources section, define an Elastic IP (EIP) that will be assigned to the NAT gateway:
    Type: AWS::EC2::EIP 
      Domain: vpc
  1. Create the NAT gateway resource, assigning it the EIP you just defined in the public subnet:
    Type: AWS::EC2::NatGateway 
      AllocationId: !GetAtt EIP.AllocationId 
      SubnetId: !Ref PublicSubnetId

  1. Finally, define the route to the NAT gateway and associate it with the private subnet’s route table:
    Type: AWS::EC2::Route 
      RouteTableId: !Ref RouteTableId 
      NatGatewayId: !Ref NatGateway
  1. Save the template with a known filename, for example, 07-02-NATGateway.yaml.
  2. Launch the template with the following CLI command:
      aws cloudformation create-stack \
        --stack-name nat-gateway \
        --template-body file://07-02-NATGateway.yaml \
        --parameters \
        ParameterKey=RouteTableId,ParameterValue=<route-table-id> \

How it works…

The parameters that are required for this recipe are as follows:

  • A public subnet ID
  • A private subnet route table ID

The public subnet ID is needed to host the NAT gateway, which must have internet access. The private subnet route table will be updated with a route to the NAT gateway.

Using the AWS NAT gateway service means that AWS takes care of hosting and securing the service for you. The service will be hosted redundantly in a single AZ.

You can use this recipe multiple times to deploy NAT gateways in each of your private subnets. Just make sure the public subnet and the private subnet are in the same AZ.

In the unlikely (but possible) event of an AZ outage, you should deploy a NAT gateway per subnet. This means that if one NAT gateway goes offline, instances in the other AZ can continue to access the internet as normal. You are deploying your application in multiple subnets, aren’t you?

This recipe will only work if you have created your own private subnets, as the default subnets in a new AWS account are all public. Instances in a public subnet have direct access to the internet (via an IGW), so they do not need a NAT gateway.

See also

  • The Creating a VPC and subnets recipe

Comments are closed.