Azure Route Tables: Controlling Network Traffic
Traffic inside an Azure VNet follows routes. Most of the time, Azure handles routing automatically and you never think about it. But when you need traffic to pass through a firewall before reaching its destination, or you need to block internet access for a subnet, or you want to force traffic through a VPN — that is when route tables come in.
How Azure routes traffic by default
Every subnet in Azure has a set of system routes created automatically. These routes define the default path for different types of traffic:
VNet-local routes: Traffic destined for any address in the VNet’s address space goes directly to the destination VM. No gateway, no hop.
Internet route: Traffic destined for addresses outside the VNet goes to the internet via Azure’s edge routers, provided the source has a public IP or NAT gateway.
Peering routes: When you peer two VNets, Azure automatically adds routes so traffic destined for the peered VNet’s address space routes correctly.
You cannot see or edit system routes directly, but you can override them with a route table attached to a subnet.
When you need a route table
You need a custom route table in these scenarios:
Forced tunneling. You want all internet-bound traffic from a subnet to go through Azure Firewall or a third-party NVA before leaving Azure. By default, traffic goes directly to the internet. A route table with a 0.0.0.0/0 route pointing to the firewall forces all internet traffic through inspection.
Hub-and-spoke with centralized inspection. In a hub-and-spoke network, spoke VNets peer to the hub. Without route tables, spoke-to-spoke traffic goes directly between spokes. If you want all east-west traffic to pass through a hub firewall, route tables in each spoke redirect that traffic to the hub.
On-premises routing. When using a VPN or ExpressRoute, you sometimes need route tables to control which subnets route to on-premises and which ones don’t.
Next hop types explained
Every route has a next hop — where traffic goes after matching the route. Azure supports these next hop types:
| Next hop type | What it means | When to use |
|---|---|---|
| VirtualAppliance | Send to a specific private IP (firewall or NVA) | Routing through Azure Firewall or third-party NVA |
| VirtualNetworkGateway | Send to a VPN or ExpressRoute gateway | Forcing traffic to on-premises over a gateway |
| VnetLocal | Normal VNet routing | Default behavior; rarely set manually |
| Internet | Send to the public internet | Overriding a more specific deny route |
| None | Drop the traffic | Blocking traffic to specific destinations |
Creating and assigning route tables
Build a route table that forces all internet traffic through Azure Firewall (a common production pattern):
# Create the route table
az network route-table create \
--name rt-spoke-web \
--resource-group rg-prod-networking \
--location eastus \
--disable-bgp-route-propagation trueThe —disable-bgp-route-propagation true flag prevents VPN gateway routes from overriding your custom routes. Set this to true when using a hub firewall to control all traffic.
# Add a default route pointing to Azure Firewall's private IP
az network route-table route create \
--name route-to-internet \
--route-table-name rt-spoke-web \
--resource-group rg-prod-networking \
--address-prefix 0.0.0.0/0 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address 10.0.0.4
# Add a route to drop traffic to a specific bad actor IP range
az network route-table route create \
--name route-block-badactors \
--route-table-name rt-spoke-web \
--resource-group rg-prod-networking \
--address-prefix 198.51.100.0/24 \
--next-hop-type None
# Associate the route table with a subnet
az network vnet subnet update \
--name snet-web \
--resource-group rg-prod-networking \
--vnet-name vnet-prod-eastus-001 \
--route-table rt-spoke-webList all routes in a route table:
az network route-table route list \
--route-table-name rt-spoke-web \
--resource-group rg-prod-networking \
--output tableCheck the effective routes on a VM’s network interface to see what routing is actually in effect:
az network nic show-effective-route-table \
--name vm-web-01VMNic \
--resource-group rg-prod-compute \
--output tableThis command is invaluable for debugging. It shows you the actual routes being applied to a NIC, including system routes, user-defined routes, and peering routes, with their sources and priorities.
Real failure mode: the routing loop
A routing loop is when traffic bounces between two hops indefinitely, never reaching its destination. This happens more often than you’d expect when setting up hub-and-spoke routing.
Scenario: You have a hub VNet with Azure Firewall at 10.0.0.4. You add a route table to the firewall’s subnet that says “send all traffic (0.0.0.0/0) to the internet.” But you also have a route in the same table that sends traffic back to the firewall. The packet goes: web server → firewall → firewall → firewall, forever.
The fix is to never put a route table on the AzureFirewallSubnet itself. Route tables belong on the spoke subnets pointing traffic toward the firewall. The firewall subnet uses system routes to reach its destinations directly.
When routing through a virtual appliance, IP forwarding must be enabled on the NVA’s network interface. Without it, the appliance drops packets it did not originate. Enable it with: az network nic update —name <nic-name> —resource-group <rg> —ip-forwarding true
Common mistakes
- Attaching a route table to the GatewaySubnet incorrectly. The GatewaySubnet supports route tables but with limitations. Adding routes that redirect VPN gateway traffic to a different hop will break site-to-site VPN connectivity. Only add routes to GatewaySubnet if you fully understand the implications for BGP route exchange.
- Not enabling IP forwarding on the NVA. If you route traffic through a VM acting as a firewall or router, that VM’s NIC must have IP forwarding enabled. Without it, the OS silently drops packets not destined for the VM’s own IP. This looks like total connectivity loss with no clear error.
- Overriding peering routes unintentionally. A 0.0.0.0/0 route in a route table overrides the default internet route. A more specific route like 10.0.0.0/8 set to None will silently drop traffic to peered VNets using that address space. Always check effective routes after adding a route table to a subnet.
Summary
- Azure system routes handle default VNet, peering, and internet routing automatically. You cannot edit them, but you can override them with route tables.
- A route table is a collection of user-defined routes that you associate with a subnet.
- Use VirtualAppliance next hop to route traffic through a firewall or NVA; use None to drop traffic to specific destinations.
- Always check effective routes with
az network nic show-effective-route-tableafter making routing changes. - Never create a routing loop by applying route tables to the firewall’s own subnet.
Frequently asked questions
What is a user-defined route in Azure?
A user-defined route (UDR) is a custom routing rule you create in a route table to override Azure system routes. UDRs let you send traffic to a specific next hop — such as a network virtual appliance or VPN gateway — instead of using Azure default routing.
What is the difference between system routes and user-defined routes?
System routes are created automatically by Azure and handle basic connectivity within the VNet, to the internet, and to peered VNets. User-defined routes override system routes when more specific paths match, letting you redirect traffic through firewalls or gateways.
Can I delete Azure system routes?
No. System routes cannot be deleted. You can only override them by adding a user-defined route with the same destination prefix — Azure always prefers more specific routes and user-defined routes over system routes of equal specificity.