In this post, I discuss the differences between Azure default routes and user defined routes (UDR), including the configuration options available when creating a user defined route.
When we create Virtual Networks in Azure, the Azure platform automatically creates a route table for each subnet located inside a Virtual Network. To simplify, a route table is like a set of instructions. For example, a Virtual Machine asks the route table for directions. “Hello Route table, how do I get to this destination?”. The route table provides the Virtual Machine with the next hop, such as, if you wish to get to this destination, this is how you get there.
The default route table automatically created by Azure includes a number of default system routes. These system routes can not be modified or deleted, however, you can override the routes by creating custom routes, also known as User Defined Routes (UDR’s). These are routes created by the user, as in you, and can be modified and deleted as needed. I’ll cover UDR’s later in this post.
Note: This post is intended to provide a basic understanding of route tables. It is important to carefully plan your routing in your production environment, as incorrect routing configuration could lead to major issues.
How to view the Azure system default routes
One of the ways to view the default routes automatically created by Azure is as follows,
1. Locate a Virtual Machine in the Azure Portal
2. From the left pane, under settings, click Networking.
3. Click the network interface located under the IP configuration drop down menu as shown below.
4. From the left pane, scroll down and click Effective Routes, located under the Help section.
Allow a few seconds for the route table to load. We’ll study the default routes in the next section.
What is visible inside the Route Table
We see a number of active default routes, I have taken a small snippet and displayed it below.
The routes in the diagram are as follows.
Source: Default
These are default routes created by Azure and can not be modified or deleted.
State: Active
The state of the route. In the image above, active, meaning the route is enabled.
Address Prefixes: 10.2.0.0/16 and Next Hop of Virtual Network
The address space used for my Virtual Network is 10.2.0.0/16. That’s the IP address name space I configured when I created the Virtual Network. When I configured this address space, Azure automatically created a default route. You may have heard or read that resources inside an Azure VNET (Virtual Network) including resources in different subnets within a VNET can communicate with each other by default. This is the default route which allows that communication to happen.
For example, the below image displays one Virtual Network named VNET1. The VNET (Virtual Network) includes Subnet1 and Subnet 2. Each Subnet includes one Virtual Machine (VM1 and VM2). By default VM1 and VM2 can communicate with each other inside VNET1. If we were to deploy additional Virtual Machines to Subnet1 or Subnet2, all VM’s would be able to communicate with each other. This is the default behavior made possible by this default route.
Address Prefixes: 0.0.0.0/0 and Next Hop of Internet
When we build a new Virtual Machine (VM) in Azure, did you know that the Virtual Machine has outbound internet connectivity enabled by default? Meaning that I could logon to that Virtual Machine and browse the internet such as cloudbuild.co.uk and other websites. How? This is the default route which allows outbound Internet. This is like a catch all route, so if a route is not already located in the route table, Azure will route traffic for any address not specified by an address range within a Virtual Network to the Internet. In simple terms, “if a route does not exist, send it to Internet via 0.0.0.0/0”. However, there is one important exception to note, if the destination is for one of Azure’s services, Azure routes the traffic directly to the service over Azure’s private backbone network, rather than routing the traffic to the Internet.
You may be thinking, “resources have outbound internet connectivity by default. Is this secure?”. If you have had this thought, it’s good to know that you have security in mind, and you’re right, this is not secure by default. However, this default behavior is due to change in September 2025. Check out the following post for details, Default outbound access for VMs in Azure will be retired September 2025.
Next Hop: None
Traffic destined to these address prefixes is dropped, it goes no where and will not leave the subnet. For example, when I created my VNET, I used an address space of 10.2.0.0/16 and we can see a default route for that in the route table above. I did not configure any other IP address name spaces such as 10.0.0.0/8 or 172.16.0.0/12 or 192.168.0.0/16, therefore Azure creates a default route to drop this traffic. Why? because I am not using these private IP ranges. However, if at a later date, I do decide to use one of these IP ranges in my VNET, Azure will automatically amend the next hop of none, to Virtual Networking. So none refers to not allowing traffic destined for that address prefix out of the subnet.
So that is an overview of the default routes, however, there is something to keep in mind. As you enable additional services such as VNET Peering and Virtual Network Gateway to name a couple, Azure will continue to create default system routes. For example, If I was to peer two Virtual Networks, VNET1 to VNET2. Let’s say VNET1 is located in the region UK South and VNET2 in region UK West. I have a requirement to connect the Virtual Networks together to allow resources in VNET1 to communicate with resources in VNET2. Peering would allow me to connect the Virtual Networks and the Azure platform will create a new default route automatically to allow resources to communicate with each other between the Virtual Networks. Below is a route which is created by Azure after I peer to another VNET configured with an IP address name space of 10.3.0.0/16. This address space belongs to the VNET I established a peer with meaning resources in VNET1 know how to get to resources in the peered Virtual Network of VNET2.
What if we want to override a default route or create additional routes?
We know that the default routes can not be deleted or modified. However, we can create custom routes also known as a User Defined Route (UDR) to override the default routes.
When we create custom/user defined routes, they are combined with the default system routes. However, if there are conflicting route assignments, user defined routes override the default routes. For example, we have a default system route of 0.0.0.0/0 with next hop to the Internet. This means traffic from a server is allowed to access the internet outbound. We decide to override this route because we want to route our traffic to a Firewall instead of being allowed unrestricted access to the Internet. We could create a custom route of 0.0.0.0/0 with a next hop of Virtual Appliance, and specify a firewall IP address. We now have a conflict because we have two routes with 0.0.0.0/0. One route to the Internet and one to a Firewall. In this case the default system route would change from active to invalid, and the custom route sending traffic to the firewall will take priority and display a status of active. As show in the image below.
We will discuss custom/user defined routes including next hop choices in the next sections.
Azure Custom/User Defined Routes Explained
As explained earlier in this post, we can create custom/user defined routes to override the default system routes or create new routes in addition to the default routes. Let’s dig a little deeper.
Let’s say in our scenario we deploy a simple hub spoke topology as shown in the diagram below.
We know that by default VM1 and VM2 are allowed outbound internet connectivity. Can you remember which default route allows this routing to take place? Remember the default system route 0.0.0.0/0 with next hop of Internet? That’s the one. We also know that Virtual Machines in a VNET can communicate by default, so in VNET1 shown in the image above, VM1 and VM2 both residing in different subnets can communicate with each other. Can you remember which default system route allows this communication to happen within a Virtual Network? We discussed this further up in this post. I’ll let you go and check. 🙂
Creating a custom route table to route traffic to a Firewall
What if there was a requirement to override the default system route of allowing Virtual Machines to route out to the Internet using the default route of 0.0.0.0/0 and next hop Internet. As an example, let’s say in the diagram below, we wanted to route traffic for VM1 located in VNET1 to a firewall deployed in HubVNet. How would we do this? We would go into the Azure Portal, create a route table and add a custom/user defined route. We’ll cover how to do this in the next section below.
Note: you could also use other methods to deploy resources in Azure such as Powershell, CLI, ARM Templates, Azure Bicep or third party tools such as Terraform. I am focusing on deploying via the Azure Portal in this post.
Let’s go through the process of creating a route table and custom routes.
1. In the Azure Portal, search for Route tables
2. Click Route tables to create a new one
3. Input the details as required. I have inputted a few details below for demo purposes.
Propagate gateway routes: If you plan to associate the route table to a subnet in a virtual network that’s connected to your on premises network through a Virtual Network Gateway, and you don’t want to propagate your on premises routes to the network interfaces in the subnet, set Virtual Network Gateway route propagation to No.
When you disable route propagation, the system doesn’t add routes to the route table of all subnets with your Virtual Network Gateway routes. This process applies to both static routes and BGP (Border Gateway Protocol) routes. Connectivity with VPN connections is achieved using custom routes with a next hop type of Virtual Network Gateway. Route propagation shouldn’t be disabled on the GatewaySubnet. The gateway will not function with this setting disabled. If you set Propagate gateway routes to NO and associate the route table to the spoke subnets, the VMs in those subnets do not get the Virtual Network Gateway routes.
4. Click Review + Create
5. Once created, open the newly created Route Table. It will be an empty table without any routes.
6. Let’s create a User Defined Route. From the left pane, click Routes
7. Click the +Add button
8. We have a few options as shown in the image below.
In the next section we will go through these user defined route configuration options.
Azure User Defined Route configuration options explained
Route name: give the route a suitable name.
Destination Type:
We have two options available in the drop down as shown above. We have,
IP Addresses (Address prefixes)
Here you type the destination IP address range. Where is the resource such as the Virtual Machine wanting to go? For example, in the image below, resources in VNET1/Subnet1 are required to communicate with resources located in VNET2/SubnetA. We would specify the address space of VNET2/SubnetA as 10.2.1.0/24, along with some additional configuration we cover later in this post. For now let’s focus on the text highlighted red in the diagram below, destination 10.2.1.0/24.
Why do we need to create a route for VM1 to communicate with VM3 through HubVNET?
VNET peering is non-transitive by default, which means that traffic from VNET1 won’t be able to reach a resource in VNET2 through a VNET in the middle. As shown in the diagram below.
Another example which may help to understand non-transitive. We have three letters A B C. Non-transitive in this example would mean that A and B can talk to each other. B and C can talk to each other. However if A wanted to talk to C or C wanted to talk to A, they could not go through B to reach each other. The same applies with VNET peering. We would need to create a user defined/custom route for this communicate between VNET1 and VNET2 to be possible as per the diagram below.
Service Tag:
From the destination type drop down, we have another option of Service Tag. A service tag includes a group of IP addresses from an Azure service. Microsoft manages the addresses included in the service tag and automatically updates the service tag as addresses change. Therefore, minimising the complexity of frequent updates to user defined routes and reducing the number of routes you need to create. In simple terms, a service tag is a group of IP addresses managed by Microsoft. If new IP’s are added or decommissioned, Microsoft manage this process so we don’t have to. If there was a requirement for you to route traffic to an Azure Service, you wouldn’t need to specify the IP ranges for that service as you could use a built in managed service tag which already includes all the required IP addresses.
Next hop type
The next hop type determines the type of device that traffic is forwarded to when it matches the address prefix/destination type of the route. For example, if the resource wants to reach a specific Virtual Machine in another Virtual Network, how does it get there? Firstly the destination is matched and then the traffic is forwarded to the next hop type such as a Firewall.
Let’s go through the options in the Next hop type drop down list.
Next hop: Virtual Network Gateway
You’ll notice that when you click Virtual Network Gateway, the option to type a Next hop address is greyed out. This is by design. Going off topic slightly but still related, when we configure peering between Virtual networks, there are configuration options available which we must configure if we require for the VNETs to use an Azure Virtual Network Gateway. I won’t be going into details on VNET peering, but I have created a post explaining VNET peering configuration at the following link Azure Virtual Network Peering Options Explained.
Back to next hop of Virtual Network Gateway, to allow for this to work we need to configure two settings.
1. Configure VNET peering options as documented in the link I shared above.
2. Create a User Defined Route
But why use Virtual Network Gateway as a next hop? you may need to route traffic from a VNET to on premises through a Virtual Network Gateway. You may already be aware that one of the use cases of a Virtual Network Gateway is to connect your Azure environment to on-premises. Or you could use a Virtual Network Gateway to forward traffic from one VNET to another in a hub spoke topology. Example, a Virtual machine in VNET1 needs to communicate with a Virtual Machine in VNET 2 via a VNETHub. A Gateway located in the VNETHub could be used as a forwarder to route traffic from VNET1 to VNET2.
Next hop: Internet
Next hop of Internet is one we came across earlier. There was a default route of 0.0.0.0/0 with a next hop of Internet. If you don’t override this route, Azure routes all traffic destined to IP addresses not included in the address prefix of any other route, to the Internet. You may wish to route the traffic to Network Virtual Appliance such as a Firewall or an inspection/logging appliance.
However, if needed, you can specify Internet as a next hop when you want to explicitly route traffic destined to an address prefix directly out to the Internet, or if you want traffic destined for Azure services with public IP addresses kept within the Azure backbone network. As explained earlier in this post, if traffic is destined for Azure services with public IP addresses, that traffic is kept within the Azure private backbone network and does not route out to the Internet.
Next hop: Virtual Appliance
A virtual appliance is a Virtual Machine that typically runs a network application, such as a firewall. You can use a next hop of Virtual Appliance also known as a Network Virtual Appliance (NVA) to route traffic to an Azure Firewall, Cisco Firewall, Palo Alto Firewall, Traffic Inspection Appliance, and more. Azure supports a number of third party appliances available from the Azure Market Place. You can also access the market place from the Azure portal at portal.azure.com
For example, as per the image below, we have a route table associated with VNET1/Subnet1 with a destination of 10.2.1.0/24 which belongs to VNET2. We have a HubVNet between both Virtual Networks. We know that VNET peering is non-transitive so we associate a route table to VNET1/Subnet1 instructing resources that if there is a requirement to communicate with resources in VNET2/SubnetA, the next hop is a virtual appliance. The virtual appliance in this case is an Azure Firewall located in HubVNet.
Next hop: None
Specify none when you want to drop traffic to an address prefix, rather than forwarding the traffic to a destination. None also represents a black hole. Packets forwarded to a black hole will not be forwarded at all. You will also notice a number of default routes with a next hop of none. This is because Azure creates system default routes for reserved address prefixes with None as the next hop type. If you decide to add another address prefix in your Virtual Network in future, Azure will amend the default route from none to Virtual Network. In the image below the option to specify a next hop address is greyed out as we’re dropping the traffic, it’s going no where, so we don’t need to specify an address.
Next hop: Virtual Network
We came across next hop of Virtual Network earlier. Can you remember where? It was a default system route created automatically which allows resources to communicate with each other inside a Virtual Network. We also have the option available when creating a User Defined Route with the Next hop address greyed out, as shown in the image below.
A question you may have, if there is already a system route which allows resources to communicate inside a Virtual Network, why would you want to create a user defined route with next hop of Virtual Network?
The default route we visited earlier allows all traffic within the IP address name space of 10.2.0.0/16 to communicate with each other. Azure automatically added this route for all subnets within the VNET, so if I created three subnets in my VNET, all subnets will include a default route with next hop to Virtual Network of 10.2.0.0/16. For example, I have the subnets below configured in VNET1,
Subnet1 10.2.1.0/24
Subnet2 10.2.2.0/24
Subnet3 10.2.3.0/24
According to the default route shown in the image below, all resources inside the three Subnets above can communicate with each other within VNET1. This means that traffic sent to any address between 10.2.0.1 and 10.2.255.254 would be routed within the Virtual Network. If I created additional Subnets in future, they would automatically be allowed to communicate with resources in Subnet1, Subnet2 and Subnet3.
But this does not answer why we would want to create a user defined route with next hop of Virtual Network. Let’s move onto a scenario with a possible use case.
Scenario
1. We have a requirement to force all traffic from 10.2.0.0/16 to a Network Virtual Appliance (NVA) for inspection and logging purposes. We must override the default route of next hop of Virtual Network. The virtual appliance is located in the same VNET, but in a different subnet. You may be thinking, we could add a route as follows, destination 10.2.0.0/16 with next hop of the IP address of the Virtual appliance.
Correct, but let’s add a little twist to this scenario,
2. Traffic destined for addresses between 10.2.0.1 and 10.2.0.254 (10.2.0.0/24) remains within SubnetA, rather than being routed to the virtual appliance, because there is no requirement for inspecting or logging the traffic. So the aim here is that if machines within SubnetA communicate with each other within the subnet, there is no requirement to route this traffic to a Virtual Appliance.
The diagram below sums up the above scenario. Traffic from SubnetC needs to be routed to the NVA located in SubnetB for packet inspection/logging. Traffic between VM1 and VM2 inside SubnetA is not routed to the NVA, however, if VM1 or VM2 need to communicate outside of SubnetA, such as communicating with VM3 or VM4 in SubnetC, then that traffic needs to be routed to the NVA first.
How would you accomplish this?
First, we create a User Defined Route with a destination of 10.2.0.0/16 and next hop of virtual appliance 10.2.1.4 as shown in the image below. This route would override the default system route of 10.2.0.0/16 with next hop of Virtual Network.
Below is an image showing what the routes would look like once we apply the route table to SubnetA. As you can see the default route has become invalid and all traffic for 10.2.0.0/16 now routes through an Network Virtual Appliance which has an IP address of 10.2.1.4.
This routes all traffic inside the Virtual network 10.2.0.0/16 to a Network Virtual appliance.
However, we have one more requirement. We don’t require traffic communicating inside Subnet A 10.2.1.0/24 (between Virtual Machines) to be routed to the NVA. But, according to the route we created earlier, all traffic from all subnets will be routed to the NVA.
To resolve scenario 2, we create another route as shown in the image below. The image shows a User Defined Route with destination of 10.2.0.0/24 (SubnetA) and next hop Virtual Network.
This is what the route table looks like now,
We now have two active routes. Traffic for the address prefix 10.2.0.0/16 is routed to the Virtual Appliance. Traffic for the address prefix 10.2.0.0/24 (SubnetA) keeps traffic within the Subnet.
So which user defined route will apply first as both meet the criteria? It’s the one with the longer prefix, in this case CIDR notation 10.2.0.0/24 has a longer prefix and takes priority when traffic is destined for IP’s in the range of 10.2.0.1 – 10.2.0.254 which belongs to SubnetA.
When outbound traffic is sent from a subnet, Azure selects a route based on the destination IP address, using the longest prefix match algorithm. For example, a route table has two routes: One route specifies the 10.2.0.0/24 address prefix, while the other route specifies the 10.2.0.0/16 address prefix. Azure directs traffic destined for 10.2.0.5 to the next hop type specified in the route with the 10.2.0.0/24 address prefix. This process occurs because 10.2.0.0/24 is a longer prefix than 10.2.0.0/16, even though 10.2.0.5 falls within both address prefixes.
So what if there was an IP of 10.2.1.7? Azure directs traffic destined for 10.2.1.7 to the next hop type specified in the route with the 10.2.0.0/16 address prefix. This process occurs because 10.2.1.7 isn’t included in the 10.2.0.0/24 address prefix, making the route with the 10.2.0.0/16 address prefix the longest matching prefix.
If you wish to learn more about longest prefix matching, the following article explains the process in detail. Longest Prefix Match Routing (I am not affiliated with this company).
How to associate a route table to a subnet
Once you have created a route table with your user defined routes, you can attach a route table to a subnet. A route table can be associated to zero or more subnets. Route tables aren’t associated to Virtual Networks. You must associate a route table to each subnet you want the route table associated to.
To associate a route table with a subnet,
1. Search and click Route tables
2. Click the route table you want to associate to a subnet
3. From the left pane, under Settings, click subnets.
4. Click Associate
5. Locate the Subnet and and click OK
and that’s it. I hope you found the post useful.
See you at the next one
Nicely explained Imran. Thanks bro
Thanks Sandeep
Thanks, great explain