You can control AKS egress traffic using User-Defined Routes (UDRs) by forcing all outbound traffic through a network virtual appliance (NVA) or Azure Firewall.
Here’s a common scenario: you have an AKS cluster and need to ensure all its outbound traffic goes through a firewall for inspection and policy enforcement before it reaches the internet or other Azure services.
Let’s see this in action. Imagine we have an AKS cluster in a VNet, and we want to route all its traffic through an Azure Firewall.
First, set up your VNet and AKS cluster. You’ll likely have a subnet for your AKS nodes (e.g., aks-subnet) and another for your Azure Firewall (e.g., fw-subnet).
# Example VNet and subnet creation (if not already done)
az network vnet create \
--name myVnet \
--resource-group myResourceGroup \
--location eastus \
--address-prefix 10.1.0.0/16
az network vnet subnet create \
--name aks-subnet \
--resource-group myResourceGroup \
--vnet-name myVnet \
--address-prefix 10.1.1.0/24
az network vnet subnet create \
--name fw-subnet \
--resource-group myResourceGroup \
--vnet-name myVnet \
--address-prefix 10.1.2.0/24 # Azure Firewall requires a dedicated subnet named AzureFirewallSubnet
# Deploy AKS (ensure it's in aks-subnet)
az aks create \
--resource-group myResourceGroup \
--name myAksCluster \
--location eastus \
--vnet-subnet-id "/subscriptions/<sub_id>/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/aks-subnet" \
--network-plugin azure --dns-service-ip 10.1.0.10 \
--docker-bridge-address 10.1.0.1/24 \
--service-cidr 10.1.0.0/24
Next, deploy Azure Firewall. It needs a public IP and must be in a subnet named AzureFirewallSubnet.
# Create a public IP for Azure Firewall
az network public-ip create \
--name fw-public-ip \
--resource-group myResourceGroup \
--location eastus \
--allocation-method Static
# Create Azure Firewall
az network firewall create \
--name myAzureFirewall \
--resource-group myResourceGroup \
--location eastus \
--public-ip-address fw-public-ip \
--vnet-name myVnet \
--threat-intel-mode Alert
# Get the Azure Firewall's private IP
FW_IP=$(az network firewall show \
--name myAzureFirewall \
--resource-group myResourceGroup \
--query "ipConfigurations[0].privateIpAddress" \
-o tsv)
echo $FW_IP
Now, the core of controlling egress: User-Defined Routes. We need to create a route table and associate it with the aks-subnet. The route table will tell traffic from aks-subnet where to go.
The critical route is for 0.0.0.0/0 (all internet traffic). This route will point to the Azure Firewall’s private IP address as the next hop.
# Create a route table
az network route-table create \
--name aksegress-routetable \
--resource-group myResourceGroup \
--location eastus
# Add the default route to Azure Firewall
az network route-table route create \
--name DefaultRoute \
--resource-group myResourceGroup \
--route-table-name aksegress-routetable \
--address-prefix 0.0.0.0/0 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address $FW_IP
# Associate the route table with the AKS subnet
az network vnet subnet update \
--name aks-subnet \
--resource-group myResourceGroup \
--vnet-name myVnet \
--route-table aksegress-routetable
With this setup, any traffic originating from a pod in your AKS cluster (which resides in aks-subnet) destined for anywhere outside the VNet (like the internet) will first be routed to the Azure Firewall’s private IP address. The firewall then applies its rules (network and application) before forwarding the traffic.
You’ll also need to ensure Azure Firewall has appropriate network rules to allow the desired egress traffic (e.g., to www.google.com on port 443).
# Example Azure Firewall Network Rule to allow outbound HTTPS to Google
az network firewall network-rule create \
--collection-name NetworkRules \
--rule-name AllowGoogleHTTPS \
--firewall-name myAzureFirewall \
--resource-group myResourceGroup \
--protocols TCP \
--source-addresses 10.1.1.0/24 \
--destination-addresses 172.217.160.142 \
--destination-ports 443 \
--action Allow
The most surprising true thing about this setup is that the next-hop-ip-address in the UDR points to the private IP of the Azure Firewall, not its public IP. The Azure Firewall is designed to intercept traffic routed to its private IP on its AzureFirewallSubnet and then uses its own NAT capabilities to forward it out using its public IP.
The next concept you’ll likely encounter is how to inspect and manage the actual traffic logs generated by Azure Firewall.