AWS: How to Create a Static IP Address Using a NAT Gateway

Image for post
Image for post
Photo by Martin Péchy from Pexels

This tutorial will show you how to setup a static IP address (using a NAT (Network address translation) gateway on Amazon’s AWS) for 3rd-party services that require a white-listed source IP address.

What we want is to route all outgoing requests through a static IP address using our NAT gateway.

If you are new to AWS or DevOps in general, this might take some getting used to. From my little experience, setting most things up in AWS usually involves non-linear steps. I still get confused a lot! Here are a few things to get familiar with on AWS before we start:

First, there is the Amazon VPCVirtual Private Cloud.

A virtual private cloud (VPC) is a virtual network dedicated to your AWS account. It is logically isolated from other virtual networks in the AWS Cloud. You can launch your AWS resources, such as Amazon EC2 instances, into your VPC.

Think of this as a fluffy tuft of cloud in the sky filled with a bunch of IP addresses that you can use as you please!

Next we have something called a Subnet.

A subnet is a way for you to divide your little cloud of IP addresses into smaller groups of IPs. This way, you can make one part of your virtual cloud public while keeping other parts of the cloud private.

To make a subnet public, we need to point it to an Internet Gateway (pretty self explanatory).

If a subnet’s traffic is routed to an internet gateway, the subnet is known as a public subnet.

On the other hand:

If a subnet’s default traffic is routed to a NAT instance/gateway or completely lacks a default route, the subnet is known as a private subnet.

On Amazon AWS, if you want to host a website or a web app, you would create a server instance (Amazon EC2) and put it in a public subnet. That way, anyone can find it on the web. You can even have a fleet of server instances in your subnet and put them behind a load balancer.

Here is the thing, they will all have different IP addresses plus when a server instance is shutdown, it loses it’s IP address! Which brings us back to the original problem — FINALLY! If we are using a 3rd-party service who’s API will reject requests unless the source IP has been previously white-listed, we will have a problem on our hands.

A NAT Gateway can have a dedicated IP assigned to it so that any request coming from any server instance in your subnet and routed through the gateway will have the same source IP address.

But first, let’s look at what a NAT gateway does:

You can use a network address translation (NAT) gateway to enable instances in a private subnet to connect to the internet or other AWS services, but prevent the internet from initiating a connection with those instances.

You will see that when a subnet is hooked up to a NAT gateway it can no longer be reached (inbound traffic) directly from the web and you can do requests (outbound traffic) via the NAT gateway. But we want both inbound and outbound traffic, yes?

Image for post
Image for post

So we have two options here (well, I will only cover two options): using a Lambda function or using a Load Balancer.

STEP 1: Create a VPC or use an existing one (see example below 👇)

Image for post
Image for post

STEP 2: Create an Internet Gateway if you don’t have one and attach to the VPC in step 1 (see example below 👇)

Image for post
Image for post

STEP 3: Create a public subnet in the same VPC and point to your Internet Gateway. Make sure that the subnet has it’s own route table (see example of my public subnet below 👇).

Image for post
Image for post
This is what the route table in my PUBLIC subnet looks like. You will see that the second row in the route table has a destination `0.0.0.0/0` and target pointing to my INTERNET Gateway (the second row isn’t added by default. You have to add it your self).

STEP 4: Create your NAT Gateway (using the VPC in step 1 and the public subnet in step 3). Then click “Create New EIP” (Elastic IP) button to create an IP address for your NAT gateway.

Image for post
Image for post
Remember to choose a PUBLIC subnet!

STEP 5: Now create a private subnet or use an existing one (in the same VPC) and point it to your NAT Gateway. Again, make sure that the subnet has it’s own route table (see example below 👇)

Image for post
Image for post
This is what the route table in my PRIVATE subnet looks like. You will see that the second row in the route table has it’s target pointing to my NAT Gateway (the second row isn’t added by default. You have to add it your self).

Now that we have our VPC, Subnets, Internet Gateway and NAT Gateway in place 😅, we will look at option 1 (Lambda function)

STEP 1: Create an IAM role for your Lambda function and attach the right policies for your Lambda function to have access to your VPC.

Image for post
Image for post
Make sure AWSLambdaFullAccess and AWSLambdaVPCAccessExecutionRole are attached.

STEP 2: Create your Lambda Function and choose the IAM role you created in step 1.

Image for post
Image for post

STEP 3: Choose the VPC and private subnet. You also need to choose a security group. I didn’t explain what a security group is because I didn’t want to throw you off! But alas, I must define what it is here at least, so:

A security group acts as a virtual firewall for your instance to control inbound and outbound traffic.

Basically it lets you define which ports are going to be open (ssh:22, http:80, ssl:443…) in your private cloud and also allows you to white-list source IP addresses (just like our 3rd API service).

Ok, back to business 👇.. Choose your security group (could be a default as long as it’s in your VPC)

Image for post
Image for post

STEP 4: Add code for your request in the editor and save (remember to save or you will lose all your changes).

Image for post
Image for post
Here, I am doing a test request to a url I created on webhook.site

STEP 5: Test!! After saving, click on the test button and use the default settings in the test event configuration.

Image for post
Image for post

You should see your request pop up on the web hook page…

Image for post
Image for post
You should see the IP address of your NAT gateway in the request details 🙌

This is a bit more elaborate 😶 than creating a Lambda function so I will put this in a separate tutorial.

You can also follow these guides:

What to keep in mind is to make sure you only choose the VPC and the private subnet you created earlier 👆 when you get to this screen 👇

Image for post
Image for post

Any server instances you put in the private subnet will be reachable (inbound traffic) via your Load Balancer and all outbound traffic will go through your NAT gateway ensuring that the 3rd party API “sees” your requests as coming from your NAT Gateway’s static IP address.

Please stay tuned for part 2.

Written by

Software Developer at Accounteer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store