Exploring the capabilities of Azure NAT Gateway

This blog post explores Azure networking, focusing on Azure NAT Gateway and the considerations encountered along the way.

In a recent project, it became necessary to integrate an application with an External API. This integration involved whitelisting the source API in the firewall to effectively restrict network access.

In the project, our application was hosted on Azure App Service. This means that our Azure App Service instance shares outbound IP addresses with other applications in Azure's deployment unit infrastructure. When multiple customers use Azure App Service applications in the same deployment unit, they share an outbound IP address. We needed to assign one of our static outbound IP addresses to the application and limit access to the External API to that IP only.

πŸ’‘
Remember that outbound IP addresses may change, especially if you scale up the App Service Plan.

Infrastructure in the beginning

Infrastructure includes Frontend, BFF, and Internal API applications, each having its own App Service Plan and subnet within a shared virtual network (VNET). BFF directs requests from the Frontend to the Internal and External APIs. BFF is also responsible for managing client credential authorization for the External API.

Traffic from the Frontend/BFF to the Internal API is limited by the App Service's inbound firewall through subnet restrictions. Usage of service endpoints (App Service) enables secure and direct connectivity within the Azure backbone network from selected subnets.

Let's explore next how to assign a static outbound IP address for the Frontend/BFF application.

Infrastructure in the beginning

Azure NAT Gateway

Azure NAT Gateway provides source network address translation (SNAT) for private instances within subnets of your Azure virtual network. On a subnet, private IPs are converted to a NAT gateway's static public IP address for outbound internet connections. When a NAT gateway is assigned to a subnet, it acts as the next hop for all internet traffic. This is exactly what we're looking for.

Prerequisites for the Azure NAT Gateway:

πŸ‘‰ Public IP Address
πŸ‘‰ Virtual Network + Subnet(s)

The Azure NAT Gateway should be configured in the Frontend/BFF subnet to enable outbound internet traffic with a static IP address in this scenario.

Azure NAT Gateway

In this scenario, the use of service endpoints and public DNS does not function exactly as depicted in the infrastructure diagram above.

The next hop towards Internal API from Frontend/BFF is also destined for the internet eventough VNET and subnets are in use. The destination of Internal API is resolved from the public DNS. When Azure NAT Gateway is assigned to the Frontend/BFF subnet with default settings, it automatically provides a static IP address for all outbound internet traffic. The new static outbound IP address from the NAT Gateway is used for both the External API and the Internal API traffic.

πŸ’‘
I recommend enabling Diagnostic logs in Azure App Service and route the HTTP logs to Azure Log Analytics Workspace. From the HTTP logs you can easily verify that the outbound IP is the correct one.

Actually, traffic flows like this:

A static outbound IP address offers practical benefits mainly when integrating with an External API. Routing traffic through a NAT Gateway incurs extra costs.

The Azure NAT Gateway features two key pricing components: hourly resource usage and data processed per gigabyte. Currently (4/25) in the West Europe Region, prices are the following:

  • Resource Hours = €0.04168 per hour (30 € / month)
  • Data Processed = €0.04168 per GB

Using Private Endpoints with the Internal API can help reduce costs, as they are slightly cheaper than Azure NAT Gateway, depending on data volumes.

Azure NAT Gateway + Private Endpoint

Now Internal API traffic is using a Private Endpoint, while all external traffic to the External API goes through a NAT Gateway. When a Private Endpoint is configured, the Internal API destination is resolved using private DNS, and the traffic does not go out to the internet.

Azure NAT Gateway (External API traffic) + Private Endpoint (Internal API traffic)

I recommend you read the below article regarding key characteristics of Service and Private Endpoints.

Azure Private Endpoint vs. Service Endpoint: A Comprehensive Guide | Microsoft Community Hub
When building secure and scalable applications on Microsoft Azure, network connectivity becomes a critical factor. Azure provides two primary methods for…

How to Configure Azure NAT Gateway + Azure App Service using Azure CLI?

  1. Login and select subscription
az login --tenant 00000000-0000-0000-0000-000000000000
az account set --subscription 00000000-0000-0000-0000-000000000000
  1. Create Resource Group
az group create --name rg-vnet-test --location westeurope
  1. Create a Public IP address for NAT Gateway
az network public-ip create --resource-group rg-vnet-test --name pip-vnet-test --sku standard --allocation static
  1. Create NAT Gateway
az network nat gateway create --resource-group rg-vnet-test --name ng-vnet-test --public-ip-addresses pip-vnet-test --idle-timeout 10
  1. Create Virtual Network
az network vnet create --name vnet-test --resource-group rg-vnet-test --address-prefix 10.0.0.0/16 --subnet-name subnet-1 --subnet-prefixes 10.0.0.0/24
  1. Create subnet
az network vnet subnet update --resource-group rg-vnet-test --vnet-name vnet-test --name subnet-1 --nat-gateway ng-vnet-test
  1. Create App Service Plan
az appservice plan create --name asp-vnet-test --resource-group rg-vnet-test --sku S1
  1. Create App Service
az webapp create --name app-vnet-test --resource-group rg-vnet-test --plan asp-vnet-test --runtime dotnet:9
  1. Enable VNET-integration to App Service
az webapp vnet-integration add -g rg-vnet-test -n app-vnet-test --vnet vnet-test --subnet subnet-1
  1. Enable Route config
az webapp config set --resource-group rg-vnet-test --name app-vnet-test --vnet-route-all-enabled