Skip to content
Get Started for Free

Route Table

Azure Route Table contains a set of rules (routes) that specify how packets should be routed in a virtual network. You can associate a route table with a subnet to override Azure’s default system routes and direct traffic to specific next-hop targets such as virtual appliances, VPN gateways, or other virtual networks. Route tables are commonly used in hub-and-spoke topologies to force traffic through a central network virtual appliance for inspection. For more information, see Virtual network traffic routing.

LocalStack for Azure provides a local environment for building and testing applications that make use of Route Tables. The supported APIs are available on our API Coverage section, which provides information on the extent of Route Table’s integration with LocalStack.

This guide is designed for users new to Route Tables and assumes basic knowledge of the Azure CLI and our azlocal wrapper script.

Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:

Terminal window
azlocal start-interception

This command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API. To revert this configuration, run:

Terminal window
azlocal stop-interception

This reconfigures the az CLI to send commands to the official Azure management REST API.

Create a resource group to hold all resources created in this guide:

Terminal window
az group create \
--name rg-rt-demo \
--location westeurope
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo",
"location": "westeurope",
"managedBy": null,
"name": "rg-rt-demo",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}

Create an empty route table to hold the custom routing rules:

Terminal window
az network route-table create \
--name rt-demo \
--resource-group rg-rt-demo \
--location westeurope
Output
{
"disableBgpRoutePropagation": false,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo",
"location": "westeurope",
"name": "rt-demo",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"routes": [],
"type": "Microsoft.Network/routeTables"
}

Create a route table with a custom route to send all internet traffic via a virtual appliance:

Terminal window
az network route-table create \
--name rt-with-routes \
--resource-group rg-rt-demo \
--location westeurope
Output
{
"disableBgpRoutePropagation": false,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-with-routes",
"location": "westeurope",
"name": "rt-with-routes",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"routes": [],
"type": "Microsoft.Network/routeTables"
}

Add a route that directs internet-bound traffic to a virtual appliance:

Terminal window
az network route-table route create \
--name route-to-internet \
--route-table-name rt-with-routes \
--resource-group rg-rt-demo \
--address-prefix 0.0.0.0/0 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address 10.0.2.4
Output
{
"addressPrefix": "0.0.0.0/0",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-with-routes/routes/route-to-internet",
"name": "route-to-internet",
"nextHopIpAddress": "10.0.2.4",
"nextHopType": "VirtualAppliance",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"type": "Microsoft.Network/routeTables/routes"
}

Add, show, and delete individual routes on an existing route table:

Add a route that directs internet-bound traffic through a virtual appliance:

Terminal window
az network route-table route create \
--name route-to-appliance \
--route-table-name rt-demo \
--resource-group rg-rt-demo \
--address-prefix 0.0.0.0/0 \
--next-hop-type VirtualAppliance \
--next-hop-ip-address 10.0.1.4
Output
{
"addressPrefix": "0.0.0.0/0",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo/routes/route-to-appliance",
"name": "route-to-appliance",
"nextHopIpAddress": "10.0.1.4",
"nextHopType": "VirtualAppliance",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"type": "Microsoft.Network/routeTables/routes"
}

Add a second route that keeps spoke traffic local to the virtual network:

Terminal window
az network route-table route create \
--name route-to-spoke \
--route-table-name rt-demo \
--resource-group rg-rt-demo \
--address-prefix 172.16.0.0/16 \
--next-hop-type VnetLocal
Output
{
"addressPrefix": "172.16.0.0/16",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo/routes/route-to-spoke",
"name": "route-to-spoke",
"nextHopType": "VnetLocal",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"type": "Microsoft.Network/routeTables/routes"
}

Then retrieve the details of the route-to-spoke route within the table:

Terminal window
az network route-table route show \
--name route-to-spoke \
--route-table-name rt-demo \
--resource-group rg-rt-demo
Output
{
"addressPrefix": "172.16.0.0/16",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo/routes/route-to-spoke",
"name": "route-to-spoke",
"nextHopType": "VnetLocal",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"type": "Microsoft.Network/routeTables/routes"
}

Delete the route-to-spoke route from the route table:

Terminal window
az network route-table route delete \
--name route-to-spoke \
--route-table-name rt-demo \
--resource-group rg-rt-demo

Retrieve the details of a route table and list all route tables in the resource group:

Terminal window
az network route-table show \
--name rt-demo \
--resource-group rg-rt-demo
Output
{
"disableBgpRoutePropagation": false,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo",
"location": "westeurope",
"name": "rt-demo",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"routes": [
{
"addressPrefix": "0.0.0.0/0",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo/routes/route-to-appliance",
"name": "route-to-appliance",
"nextHopIpAddress": "10.0.1.4",
"nextHopType": "VirtualAppliance",
"provisioningState": "Succeeded",
"type": "Microsoft.Network/routeTables/routes"
}
],
"type": "Microsoft.Network/routeTables"
}

Then list all route tables in the resource group:

Terminal window
az network route-table list \
--resource-group rg-rt-demo
Output
[
{
"disableBgpRoutePropagation": false,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo",
"location": "westeurope",
"name": "rt-demo",
"provisioningState": "Succeeded",
"routes": [ { "name": "route-to-appliance", "nextHopType": "VirtualAppliance", "nextHopIpAddress": "10.0.1.4" } ],
"type": "Microsoft.Network/routeTables"
},
{
"disableBgpRoutePropagation": false,
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-with-routes",
"location": "westeurope",
"name": "rt-with-routes",
"provisioningState": "Succeeded",
"routes": [ { "name": "route-to-internet", "nextHopType": "VirtualAppliance", "nextHopIpAddress": "10.0.2.4" } ],
"type": "Microsoft.Network/routeTables"
}
]

To apply routing rules, associate the route table with a subnet. First create a virtual network with a subnet:

Terminal window
az network vnet create \
--name vnet-demo \
--resource-group rg-rt-demo \
--location westeurope \
--address-prefix 10.0.0.0/16 \
--subnet-name subnet-demo \
--subnet-prefix 10.0.1.0/24
Output
{
"newVNet": {
"addressSpace": { "addressPrefixes": [ "10.0.0.0/16" ] },
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/virtualNetworks/vnet-demo",
"location": "westeurope",
"name": "vnet-demo",
"provisioningState": "Succeeded",
"subnets": [
{
"addressPrefix": "10.0.1.0/24",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/virtualNetworks/vnet-demo/subnets/subnet-demo",
"name": "subnet-demo",
"provisioningState": "Succeeded",
"type": "Microsoft.Network/virtualNetworks/subnets"
}
],
"type": "Microsoft.Network/virtualNetworks"
}
}

Then associate rt-demo with subnet-demo:

Terminal window
az network vnet subnet update \
--name subnet-demo \
--vnet-name vnet-demo \
--resource-group rg-rt-demo \
--route-table rt-demo
Output
{
"addressPrefix": "10.0.1.0/24",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/virtualNetworks/vnet-demo/subnets/subnet-demo",
"name": "subnet-demo",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"routeTable": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo",
"resourceGroup": "rg-rt-demo"
},
"type": "Microsoft.Network/virtualNetworks/subnets"
}

Verify the association is reflected on the subnet:

Terminal window
az network vnet subnet show \
--name subnet-demo \
--vnet-name vnet-demo \
--resource-group rg-rt-demo
Output
{
"addressPrefix": "10.0.1.0/24",
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/virtualNetworks/vnet-demo/subnets/subnet-demo",
"name": "subnet-demo",
"provisioningState": "Succeeded",
"resourceGroup": "rg-rt-demo",
"routeTable": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-rt-demo/providers/Microsoft.Network/routeTables/rt-demo",
"resourceGroup": "rg-rt-demo"
},
"type": "Microsoft.Network/virtualNetworks/subnets"
}

Delete the route tables and verify it no longer appears in the list:

Terminal window
az network route-table delete \
--name rt-demo \
--resource-group rg-rt-demo
az network route-table delete \
--name rt-with-routes \
--resource-group rg-rt-demo

Then list all route tables to confirm the resource group is now empty:

Terminal window
az network route-table list --resource-group rg-rt-demo
Output
[]

The Route Table emulator supports the following features:

  • Create and manage route tables: Full lifecycle management including create, get, update, list, and delete.
  • Sub-resource route management: Create, get, update, list, and delete individual routes within a route table.
  • Next-hop types: Support for VirtualAppliance, VnetLocal, VirtualNetworkGateway, Internet, and None.
  • Next-hop IP addresses: Store and return the next-hop IP address for VirtualAppliance routes.
  • Address prefix ranges: Store and return the address prefix for each route.
  • Tags: Apply and update resource tags on route table resources.
  • Subscription-scoped listing: List all route tables across a subscription.
  • No traffic routing: Route Table is a mock implementation. State is persisted in memory and returned faithfully, but no actual network traffic is routed according to the configured routes.
  • No subnet association enforcement: Associating a route table with a subnet is accepted but not enforced at the network level.
  • No data persistence: Route table resources and their routes are not persisted and are lost when the emulator is stopped or restarted.

Explore end-to-end examples in the LocalStack for Azure Samples repository.

OperationImplemented
Page 1 of 0
Was this page helpful?