Configure a NAT gateway for static IP address for outbound traffic from a container group
Setting up a container group with an external-facing IP address allows external clients to use the IP address to access a container in the group. For example, a browser can access a web app running in a container. However, currently a container group uses a different IP address for outbound traffic. This egress IP address isn't exposed programmatically, which makes container group monitoring and configuration of client firewall rules more complex.
This article provides steps to configure a container group in a virtual network integrated with a Network Address Translation (NAT) gateway. By configuring a NAT gateway to SNAT a subnet address range delegated to Azure Container Instances (ACI), you can identify outbound traffic from your container groups. The container group egress traffic uses the public IP address of the NAT gateway. Multiple container groups deployed in the virtual network's subnet can use a single NAT gateway.
In this article, you use the Azure CLI to create the resources for this scenario:
- Container groups deployed on a delegated subnet in the virtual network
- A NAT gateway deployed in the network with a static public IP address
You then validate egress from example container groups through the NAT gateway.
Note
The ACI service recommends integrating with a NAT gateway for containerized workloads that have static egress but not static ingress requirements. For ACI architecture that supports both static ingress and egress, please see the following tutorial: Use Azure Firewall for ingress and egress.
If you don't have an Azure subscription, create an Azure free account before you begin.
Prerequisites
Use the Bash environment in Azure Cloud Shell. For more information, see Quickstart for Bash in Azure Cloud Shell.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you're running on Windows or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Sign in with the Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
Launch Azure Cloud Shell
The Azure Cloud Shell is a free interactive shell that you can use to run the steps in this article. It has common Azure tools preinstalled and configured to use with your account.
To open the Cloud Shell, just select Try it from the upper right corner of a code block. You can also launch Cloud Shell in a separate browser tab by going to https://shell.azure.com.
When Cloud Shell opens, verify that Bash is selected for your environment. Subsequent sessions will use Azure CLI in a Bash environment, Select Copy to copy the blocks of code, paste it into the Cloud Shell, and press Enter to run it.
Sign in to Azure
Cloud Shell is automatically authenticated under the initial account signed-in with. Use the following script to sign in using a different subscription, replacing <Subscription ID>
with your Azure Subscription ID. If you don't have an Azure subscription, create an Azure free account before you begin.
subscription="<subscriptionId>" # add subscription here
az account set -s $subscription # ...or use 'az login'
For more information, see set active subscription or log in interactively
Note
To download the complete script, go to full script.
Get started
This tutorial makes use of a randomized variable. If you used an existing resource group, modify the value of this variable appropriately.
resourceGroup=resourceGroup$RANDOM
Azure resource group: If you don't have an Azure resource group already, create a resource group with the az group create command. Modify the location value as appropriate.
az group create --name $resourceGroup --location eastus
Deploy ACI in a virtual network
In a typical case, you might already have an Azure virtual network in which to deploy a container group. For demonstration purposes, the following commands create a virtual network and subnet when the container group is created. The subnet is delegated to Azure Container Instances.
The container group runs a small web app from the aci-helloworld
image. As shown in other articles in the documentation, this image packages a small web app written in Node.js that serves a static HTML page.
Create the container group with the az container create command:
az container create \
--name appcontainer \
--resource-group $resourceGroup \
--image mcr.microsoft.com/azuredocs/aci-helloworld \
--vnet aci-vnet \
--vnet-address-prefix 10.0.0.0/16 \
--subnet aci-subnet \
--subnet-address-prefix 10.0.0.0/24
Note
Adjust the value of --subnet address-prefix
for the IP address space you need in your subnet. The smallest supported subnet is /29, which provides eight IP addresses. Some >IP addresses are reserved for use by Azure, which you can read more about here.
Create a public IP address
In the following sections, use the Azure CLI to deploy an Azure NAT gateway in the virtual network. For background, see Quickstart: Create a NAT gateway using Azure CLI.
First, use the az network vnet public-ip create to create a public IP address for the NAT gateway. The gateway uses this public IP to access the Internet. You receive a warning about an upcoming breaking change where Standard SKU IP addresses are availability zone aware by default. You can learn more about the use of availability zones and public IP addresses here.
az network public-ip create \
--name myPublicIP \
--resource-group $resourceGroup \
--sku standard \
--zone 1 \
--allocation static
Store the public IP address in a variable for use during the validation step later in this script.
ngPublicIp="$(az network public-ip show \
--name myPublicIP \
--resource-group $resourceGroup \
--query ipAddress --output tsv)"
Deploy a NAT gateway into a virtual network
Use the following az network nat gateway create to create a NAT gateway that uses the public IP you created in the previous step.
az network nat gateway create \
--resource-group $resourceGroup \
--name myNATgateway \
--public-ip-addresses myPublicIP \
--idle-timeout 10
Configure NAT service for source subnet
We configure the source subnet aci-subnet to use a specific NAT gateway resource myNATgateway with az network vnet subnet update. This command activates the NAT service on the specified subnet.
az network vnet subnet update \
--resource-group $resourceGroup \
--vnet-name aci-vnet \
--name aci-subnet \
--nat-gateway myNATgateway
Test egress from a container group
Test inbound access to the appcontainer
running in the virtual network by browsing to the firewall's public IP address. Previously, you stored the public IP address in variable $NG_PUBLIC_IP
Deploy the following sample container into the virtual network. When it runs, it sends a single HTTP request to http://checkip.dyndns.org
, which displays the IP address of the sender (the egress IP address). If the application rule on the firewall is configured properly, the firewall's public IP address is returned.
az container create \
--resource-group $resourceGroup \
--name testegress \
--image mcr.microsoft.com/azuredocs/aci-tutorial-sidecar \
--command-line "curl -s http://checkip.dyndns.org" \
--restart-policy OnFailure \
--vnet aci-vnet \
--subnet aci-subnet
View the container logs to confirm the IP address is the same as the public IP address we created in the first step of the tutorial.
az container logs \
--resource-group $resourceGroup \
--name testegress
Output is similar to:
<html><head><title>Current IP Check</title></head><body>Current IP Address: 52.142.18.133</body></html>
This IP address should match the public IP address created in the first step of the tutorial.
echo $ngPublicIp
Clean up resources
When no longer needed, you can use az group delete to remove the resource group and all related resources as follows. The --no-wait
parameter returns control to the prompt without waiting for the operation to complete. The --yes
parameter confirms that you wish to delete the resources without another prompt to do so.
az group delete --name $resourceGroup --yes --no-wait
Next steps
In this article, you set up container groups in a virtual network behind an Azure NAT gateway. By using this configuration, you set up a single, static IP address egress from Azure Container Instances container groups.
For troubleshooting assistance, see the Troubleshoot Azure Virtual Network NAT connectivity.