Skip to main content

Theoretical Foundation: Configure user-defined routes


1. Initial Intuition​

Imagine a city's street system. Normally, GPS determines the shortest path between two points, and cars automatically follow that route. But in certain situations, the city hall places "mandatory detour" signs: even if GPS indicates a shorter path, cars must pass through a specific control point before reaching the destination.

In Azure, default routing works like automatic GPS: Azure knows all addresses in the VNet, peered VNets, and the internet, and automatically routes traffic through the most efficient path. User-Defined Routes (UDRs) are the "mandatory detour" signs: you explicitly instruct that certain types of traffic must pass through a specific point before reaching the destination, even if that's not the shortest path.

The most common use case is forcing all traffic from a subnet to pass through an Azure Firewall or a Network Virtual Appliance (NVA) before going to the internet or other networks. Without UDRs, traffic would go directly to the destination, without inspection.


2. Context​

In previous modules, we saw that:

  • VNets organize resources in isolated address spaces
  • Peerings connect VNets
  • NSGs control whether traffic is allowed or denied

UDRs operate in a different dimension: they don't control whether traffic is allowed, but where it passes through. It's path control, not permission control.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

UDRs are the piece that completes the Azure network security architecture. NSGs alone control inbound/outbound, but can't redirect traffic for inspection. UDRs do this redirection.


3. Concept Construction​

3.1 How Routing Works in Azure: System Routes​

Before understanding UDRs, you need to understand what happens without them. Azure automatically creates system routes for each subnet:

Destination prefixNext hopWhat it does
10.0.0.0/16 (local VNet)Virtual networkTraffic within the VNet stays in the VNet
0.0.0.0/0InternetAll non-local traffic goes to the internet
10.1.0.0/16 (peered VNet)VNet peeringTraffic to peered VNet goes via peering
192.168.0.0/16 (on-premises via VPN)Virtual network gatewayTraffic to on-premises goes via gateway
100.64.0.0/10NoneDiscarded (reserved range)

These routes are automatic and invisible, but you can see them by checking the effective routes of any NIC. They form each subnet's implicit routing table.

3.2 What is a User-Defined Route​

A UDR is an entry in a Route Table that you explicitly create. It has three components:

ComponentDescriptionExample
Address prefixThe destination: where this traffic is going0.0.0.0/0 (all internet)
Next hop typeThe type of next hopVirtualAppliance
Next hop addressThe IP of the next hop (when applicable)10.0.0.4 (Firewall IP)

3.3 Next Hop Types​

Next hop typeDescriptionWhen to use
Virtual applianceRedirects to a specific private IP (NVA, Firewall)Force traffic inspection
Virtual network gatewayForwards to the VNet's VPN/ExpressRoute gatewayRouting to on-premises via gateway
Virtual networkTraffic stays within the VNet (local routing)Override a more specific route
InternetForwards to the internet via public IPDirect internet egress
NoneDrops traffic (blackhole)Block specific routes via routing

The None type is an alternative way to block traffic via routing, without NSG. The difference from NSG: NSG returns an explicit "access denied"; None simply drops packets without notification.

3.4 Route Tables: The UDR Container​

A Route Table is the Azure resource that contains a collection of UDRs. The Route Table itself does nothing; it needs to be associated with one or more subnets. A subnet can have at most one Route Table associated. A Route Table can be associated with multiple subnets.

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

3.5 Route Precedence​

When there are multiple routes that apply to the same destination, Azure follows a precedence order:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

Example of precedence by specificity: if there's a system route for 0.0.0.0/0 β†’ Internet, and you create a UDR for 10.1.0.0/16 β†’ VirtualAppliance, traffic to 10.1.0.0/16 will use the UDR (more specific), and everything else will use the default system route. The UDR doesn't need to replace all routes; it only overlaps the ones you define.


4. Structural View​

Classic Scenario: Force Tunneling via Azure Firewall​

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

The Route Table rt-spoke-to-hub contains:

  • 0.0.0.0/0 β†’ VirtualAppliance β†’ 10.0.1.4 (Firewall)
  • 192.168.0.0/16 β†’ VirtualAppliance β†’ 10.0.1.4 (Firewall)

This ensures that all traffic leaving the Spoke VNet subnets passes through Azure Firewall, whether to internet or on-premises.

Effective Routes: The Complete View​

To understand a NIC's effective routing, Azure combines all sources:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

5. Practical Operation​

The IP Forwarding Problem​

When a UDR redirects traffic to a VM or NVA (for example, an Azure Firewall or third-party appliance), there's a critical technical requirement: the destination VM's NIC must have IP Forwarding enabled.

By default, Azure drops packets that arrive at a NIC but whose destination IP is not that NIC's IP. This is protection against spoofing. But when a VM is acting as a router or firewall, it needs to accept and forward packets destined to other IPs.

IP Forwarding needs to be enabled in two places:

  1. On the VM's NIC in Azure (NIC resource configuration in portal/CLI)
  2. In the VM's operating system (enabling IP forwarding in Linux kernel or Windows registry)

For Azure Firewall, this is managed automatically by Microsoft. For third-party NVAs (Palo Alto, FortiGate, etc.), you need to enable it manually.

# Enable IP Forwarding on NIC via CLI
az network nic update \
--name nic-nva-appliance \
--resource-group rg-networking \
--ip-forwarding true

Blackhole Route for Routing-based Blocking​

A less obvious use of UDRs is creating routing blackholes: dropping traffic to specific prefixes without using NSG. This is useful for blocking routes advertised via BGP that you don't want to be used:

# Create blackhole route to block egress to a specific range
az network route-table route create \
--route-table-name rt-application \
--resource-group rg-networking \
--name block-sensitive-range \
--address-prefix 203.0.113.0/24 \
--next-hop-type None

Route Behavior with BGP Propagation​

Route Tables have a setting called "Disable BGP route propagation". By default, routes learned via BGP from a VPN Gateway or ExpressRoute are automatically propagated to VNet subnets. If you disable this propagation in a subnet's Route Table, BGP routes don't reach that subnet.

This behavior is important in scenarios where you want to explicitly control all on-premises routing from a subnet via UDRs, without interference from automatic BGP routes.


6. Implementation Methods​

6.1 Azure Portal​

When to use: one-off creation, route verification, visual diagnostics.

Path to create Route Table: Create a resource > Networking > Route table

Path to add routes: Route table > Routes > Add

Path to associate to a subnet: Route table > Subnets > Associate or from the subnet side: Virtual Network > Subnet > Route table

Path to verify effective routes: Network interface > Help > Effective routes

6.2 Azure CLI​

Create Route Table:

az network route-table create \
--name rt-spoke-to-hub \
--resource-group rg-networking \
--location brazilsouth \
--disable-bgp-route-propagation false

Add route to force internet traffic via Firewall:

az network route-table route create \
--route-table-name rt-spoke-to-hub \
--resource-group rg-networking \
--name route-internet-via-firewall \
--address-prefix 0.0.0.0/0 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address 10.0.1.4

Add route for on-premises via Firewall:

az network route-table route create \
--route-table-name rt-spoke-to-hub \
--resource-group rg-networking \
--name route-onprem-via-firewall \
--address-prefix 192.168.0.0/16 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address 10.0.1.4

Associate Route Table to a subnet:

az network vnet subnet update \
--name subnet-application \
--vnet-name vnet-spoke \
--resource-group rg-networking \
--route-table rt-spoke-to-hub

Verify effective routes of a NIC:

az network nic show-effective-route-table \
--name nic-vm-app \
--resource-group rg-producao \
--output table

Disassociate Route Table from a subnet:

az network vnet subnet update \
--name subnet-application \
--vnet-name vnet-spoke \
--resource-group rg-networking \
--remove routeTable

List all routes from a Route Table:

az network route-table route list \
--route-table-name rt-spoke-to-hub \
--resource-group rg-networking \
--output table

6.3 PowerShell​

# Create Route Table
$routeTable = New-AzRouteTable `
-Name "rt-spoke-to-hub" `
-ResourceGroupName "rg-networking" `
-Location "brazilsouth"

# Add internet route via Firewall
Add-AzRouteConfig `
-RouteTable $routeTable `
-Name "route-internet-via-firewall" `
-AddressPrefix "0.0.0.0/0" `
-NextHopType "VirtualAppliance" `
-NextHopIpAddress "10.0.1.4" |
Set-AzRouteTable

# Add on-premises route via Firewall
Add-AzRouteConfig `
-RouteTable $routeTable `
-Name "route-onprem-via-firewall" `
-AddressPrefix "192.168.0.0/16" `
-NextHopType "VirtualAppliance" `
-NextHopIpAddress "10.0.1.4" |
Set-AzRouteTable

# Associate to a subnet
$vnet = Get-AzVirtualNetwork -Name "vnet-spoke" -ResourceGroupName "rg-networking"
$subnet = Get-AzVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name "subnet-application"
$subnet.RouteTable = $routeTable
Set-AzVirtualNetwork -VirtualNetwork $vnet

# Verify effective routes
Get-AzEffectiveRouteTable `
-NetworkInterfaceName "nic-vm-app" `
-ResourceGroupName "rg-producao" |
Format-Table

6.4 Bicep​

resource routeTable 'Microsoft.Network/routeTables@2023-05-01' = {
name: 'rt-spoke-to-hub'
location: location
properties: {
disableBgpRoutePropagation: false
routes: [
{
name: 'route-internet-via-firewall'
properties: {
addressPrefix: '0.0.0.0/0'
nextHopType: 'VirtualAppliance'
nextHopIpAddress: '10.0.1.4'
}
}
{
name: 'route-onprem-via-firewall'
properties: {
addressPrefix: '192.168.0.0/16'
nextHopType: 'VirtualAppliance'
nextHopIpAddress: '10.0.1.4'
}
}
]
}
}

// Associate to subnet
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-05-01' = {
name: 'subnet-application'
parent: vnet
properties: {
addressPrefix: '10.1.1.0/24'
routeTable: {
id: routeTable.id
}
}
}

7. Control and Security​

The Asymmetric Routing Problem​

Asymmetric routing is the most critical error when configuring UDRs with NVAs/Firewalls. It occurs when inbound traffic and return traffic travel different paths, and the inspection appliance sees only half of the flow:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

The solution is ensuring both inbound and return traffic pass through the same appliance. This is done by applying consistent UDRs in both traffic directions.

UDR on GatewaySubnet: Special Care​

Associating a Route Table to the GatewaySubnet is possible, but extremely risky. An incorrect UDR can break all VPN/ExpressRoute connectivity. Microsoft doesn't recommend putting UDRs on GatewaySubnet unless you have absolute certainty of the impact.

The only safe UDR on GatewaySubnet would be to ensure traffic from specific addresses doesn't exit via internet, but even this should be done with great care and tested in non-production environments first.


8. Decision Making​

When to use UDR vs. NSG vs. Azure Firewall?​

ObjectiveToolReason
Block traffic from a specific portNSGNSG operates at L4, simpler and more efficient
Force traffic inspection before releaseUDR + Azure Firewall/NVAUDR redirects, Firewall inspects and decides
Block traffic to a prefix via routingUDR with Next hop: NoneAlternative to NSG, more efficient for large blocks
Ensure internet egress via centralized FirewallUDR with 0.0.0.0/0 β†’ VirtualApplianceStandard force tunneling in hub-spoke
Route on-premises traffic via specific gatewayUDR with prefix β†’ VirtualNetworkGatewayPrecise control over which traffic uses the gateway

Which subnets to associate Route Tables with?​

SubnetAssociate RT?Typical configuration
Workload subnets (app, backend, db)Yes0.0.0.0/0 β†’ Firewall; on-premises prefixes β†’ Firewall
AzureFirewallSubnetYes (specific routes only)Route to on-premises via VPN Gateway
GatewaySubnetRarely, with extreme careOnly if absolutely necessary
AzureBastionSubnetNot recommendedBastion has specific routing requirements
Delegated managed service subnetsCheck service documentationSome services don't support RTs

9. Best Practices​

Always test UDRs in non-production environment first: an incorrect UDR can create routing loops or blackholes that completely interrupt subnet connectivity. A development environment where you can validate the behavior before applying to production is essential.

Verify effective routes before and after applying: use the Network Watcher effective routes tool to confirm exactly which routes are active on a NIC after applying a Route Table. This confirms that the UDR is behaving as expected.

Name routes descriptively: route-internet-via-azfw, route-onprem-192-168-via-azfw, blackhole-rfc1918-unused are names that immediately communicate the route's purpose. Routes with names like route1, route2 make maintenance and diagnosis much more difficult.

Keep Route Tables separate by function: one RT for spoke subnets that force traffic via hub, one RT for the AzureFirewallSubnet, one RT for management subnets. Sharing the same RT between subnets with very different functions makes changes more risky.

Use a shared Route Table for multiple subnets when routes are identical: if all subnets in a spoke need the same routes, a single Route Table associated to all is easier to maintain than multiple copies.


10. Common Errors​

Creating the UDR but forgetting to associate it to the subnet

The Route Table exists, routes are configured, but traffic still follows system routes. The cause is that the Route Table was not associated to any subnet. Checking the NIC's effective routes immediately shows that UDRs don't appear, revealing the problem.

Asymmetric routing due to partial UDR

The UDR is applied only to the outbound subnet (e.g.: subnet-backend β†’ Firewall), but not to the inbound subnet or return path. The Firewall sees only half of the connections, cannot maintain state, and drops return packets. All connections become intermittent or fail. The solution is to ensure that traffic from both directions of a connection passes through the same appliance.

Routing loop between NVA and Route Table

A UDR directs 0.0.0.0/0 to the NVA IP (10.0.1.4). The NVA is in the same subnet that has the Route Table. Traffic from the NVA towards the next hop loops: goes to itself. The solution is to place the NVA in a separate subnet without the redirection Route Table, or ensure that the NVA subnet's Route Table has the route 0.0.0.0/0 β†’ Internet (not β†’ VirtualAppliance).

Not enabling IP Forwarding on the NVA NIC

The UDR redirects traffic to the NVA (10.0.1.4), but traffic arrives at the NIC and is dropped because the packet's destination IP is not 10.0.1.4 (it's the final destination, like 8.8.8.8). Azure drops the packet for security. Enabling IP Forwarding on the Azure NIC AND in the NVA's operating system solves the problem.

Applying UDR to GatewaySubnet without testing

An administrator applies a Route Table to the GatewaySubnet to control on-premises traffic. The route is slightly wrong, and all VPN connectivity drops immediately. Since access to Azure is now only possible via VPN (which dropped), the administrator cannot access the portal to fix it. Always maintain an alternative access path (for example, an emergency access account with portal access via internet) before modifying critical routing.


11. Operation and Maintenance​

Diagnosis with Network Watcher​

Two Network Watcher tools are essential for routing diagnosis:

Effective Routes: shows all active routes on a NIC, including system, UDRs, BGP and peering. Shows the source of each route and which is being used for each destination.

az network watcher show-next-hop \
--resource-group rg-producao \
--vm vm-app-01 \
--source-ip 10.1.1.4 \
--dest-ip 8.8.8.8

This command directly answers: "if a VM with IP 10.1.1.4 tries to reach 8.8.8.8, what is the next hop and which route is being used?"

Connection Troubleshoot: tests end-to-end connectivity and identifies where in the path communication is being blocked or redirected.

Audit of Route Tables Without Association​

Route Tables without associated subnets are orphaned resources that have no utility but can cause confusion:

az network route-table list \
--query "[?subnets==null || length(subnets)==`0`].{Nome:name, RG:resourceGroup}" \
--output table

Important Limits​

ItemLimit
Route Tables per subscription per region200
Routes per Route Table400
Route Tables per subnet1 (only one RT per subnet)
Subnets per Route TableNo documented limit

The limit of 400 routes per Route Table is rarely reached in typical scenarios, but in environments with many on-premises networks advertised via BGP that need to be overridden by UDRs, it can be relevant.


12. Integration and Automation​

UDRs in Complete Hub-Spoke Architecture​

The complete UDR configuration in a typical hub-spoke architecture involves multiple Route Tables:

100%
Scroll para zoom Β· Arraste para mover Β· πŸ“± Pinch para zoom no celular

The Firewall subnet RT (rt-azfw-subnet) is necessary so that the Firewall knows to route traffic destined for on-premises via the VPN Gateway, instead of trying to access directly. Without it, the Firewall may drop or incorrectly route on-premises traffic.

Deploy Automation via Terraform​

resource "azurerm_route_table" "spoke_rt" {
name = "rt-spoke-to-hub"
location = var.location
resource_group_name = var.resource_group
disable_bgp_route_propagation = false

route {
name = "route-internet-via-firewall"
address_prefix = "0.0.0.0/0"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = var.firewall_private_ip
}

route {
name = "route-onprem-via-firewall"
address_prefix = "192.168.0.0/16"
next_hop_type = "VirtualAppliance"
next_hop_in_ip_address = var.firewall_private_ip
}
}

resource "azurerm_subnet_route_table_association" "app" {
subnet_id = azurerm_subnet.application.id
route_table_id = azurerm_route_table.spoke_rt.id
}

Azure Policy for Routing Compliance​

# Create policy to audit subnets without Route Table
az policy assignment create \
--name "audit-subnet-route-table" \
--policy "/providers/Microsoft.Authorization/policyDefinitions/fc5e4038-4584-4632-8c85-c0448d374b2c" \
--scope "/subscriptions/<sub-id>"

This built-in policy audits subnets that don't have an associated Route Table, helping to ensure that centralized routing via Firewall is in place on all workload subnets.


13. Final Summary​

Essential points:

  • UDRs control the path of traffic, not whether it's allowed. NSGs control permission. Both are complementary.
  • A Route Table is the UDR container. It needs to be associated to subnets to take effect. A subnet can have only one Route Table.
  • Each route has: address prefix (destination), next hop type and next hop address (when applicable).
  • UDRs have priority over system routes when they have the same prefix. More specific prefixes always win, regardless of source.

Critical differences:

  • Next hop VirtualAppliance vs. VirtualNetworkGateway: the first redirects to a private IP of NVA/Firewall; the second uses the VNet's VPN/ExpressRoute gateway.
  • Next hop None vs. NSG Deny: None drops silently (no response to sender); NSG Deny can return an explicit response. Both block traffic but through different mechanisms.
  • Route Table vs. Effective Routes: the Route Table is what you configure; the Effective Routes are the final result after combination with system, BGP and peering routes.
  • Disable BGP route propagation disabled (default): BGP routes reach the subnet. Enabled: only explicit UDRs are used, without automatic BGP routes.

What needs to be remembered:

  • For third-party NVAs, enabling IP Forwarding on the Azure NIC AND in the operating system is mandatory. For Azure Firewall, it's automatic.
  • Asymmetric routing is the most critical error: ensure that inbound and outbound traffic passes through the same inspection appliance.
  • Never apply Route Tables to the GatewaySubnet without rigorous testing; it can bring down all VPN connectivity.
  • Always verify effective routes of a NIC after applying a Route Table to confirm expected behavior.
  • The command az network watcher show-next-hop directly answers which route will be used for a specific IP pair, essential for diagnosis.
  • Route Table associated to a subnet that has resources but without configured routes still does nothing; system routes remain in effect.