Implementing Azure Routing Using PowerShell
In a previous post, How Do You Customize Routing in Azure?, I explained why we might use user defined routing in Azure. I then followed that up with a post to show you how to create a route table and routes using the Azure Portal. In this post I will show you how use PowerShell to create a route table and routes, and associate that route table to virtual subnets.
Before We Begin
Note that this post is based on Azure Resource Manager (ARM) PowerShell, so make sure that you have updated your Azure PowerShell module to the latest version first.
You can also use classic (Service Manager) PowerShell cmdlets to create user defined routes.
Once again, I’m deploying a simple solution where a customer has chosen to deploy a site-to-site VPN solution using a virtual appliance from the Azure Marketplace. The virtual appliance, a virtual machine, is on the same subnet as the other Azure virtual machines. A user defined route is required to override the system route to ensure that all traffic to the customer’s on-premises subnet(s) will be redirected through the appliance and the VPN tunnel instead of to the Internet.
The Desired Solution
User defined routing will be used to fix the above problem. A route table will be created. A single route will be added:
- AddressPrefix: The network address (192.168.1.0/24) of the on-premises network will be used as the destination address.
- NextHopType: VirtualAppliance will be used because the next hop is a virtual machine.
- NextHopIPAddress: The IP address of the virtual appliance on the Azure subnet (10.1.0.10) will be defined as the IP gateway address for this route.
When a packet is being sent from a virtual machine in the subnet to anywhere on 192.168.1.0/24, then the user defined rule will match and override the system route for routing the traffic to the Internet.
Implementing the Solution
We are using ARM PowerShell cmdlets in Azure V2, so you’ll need to log into Azure first:
List your Azure subscriptions:
Then select the subscription that you want to work with from the above results:
Select-AzureRmSubscription -SubscriptionId 9999xxxx-99xx-99xx-99xx-999999xxxxxx
I’m assuming that you already have a resource group for your deployment. If you do, then find it from the results created from the following:
My resource group is called DemoPetriAF1, so I’m going to store it in a variable for reuse.
$RgName = “DemoPetriAF1”
My appliance will be called DemoPetriAF1-1:
$VmName = “DemoPetriAF1-1”
Now I’ll list my virtual networks:
This will allow me to select my virtual network:
$Vnet = Get-AzureRmVirtualNetwork -Name "DemoPetriAF1" -ResourceGroupName $RgName
The results of the previous query show me my subnets. I can store the name of the subnet that I am customizing routing for using the following:
$SubnetName = “Subnet-1”
And then I can select my subnet:
$Subnet = $vnet.Subnets | Where-Object Name -eq $subnetName
I can also see the location (Azure region) that the virtual network is in, so I store that too:
$Location = “northeurope”
Now we can start creating some user defined routing. The first step is to create a route table.
$RouteTableName = “demopetriaf1subnet1” $RouteTable = New-AzureRmRouteTable -Name $RouteTableName -ResourceGroupName $RgName -Location $Location
Next we will add a route to the just-created route table. Note how we are setting the destination network address (192.168.1.0/24) as the AddressPrefix, configuring a virtual machine as the next hop type, and configuring the IP address of the virtual machine as the gateway to the route.
$RouteTable | Add-AzureRmRouteConfig -Name “SiteVPN” -AddressPrefix "192.168.1.0/24" -NextHopType VirtualAppliance -NextHopIpAddress "10.0.1.10" | Set-AzureRmRouteTable
Now the route table is ready, it needs to be associated with the subnet:
Set-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $Vnet -Name $SubnetName -AddressPrefix $Subnet.AddressPrefix -RouteTableId $RouteTable.Id | Set-AzureRmVirtualNetwork
You can verify your work by running the following:
Get-AzureRmRouteTable -ResourceGroupName $RgName -Name $RouteTableName
This is where you’ll go and test your routing and it will fail. This is because the Azure fabric will not allow the NIC of the virtual machine to perform IP forwarding. You must enable IP forwarding for the NIC of any virtual appliance that will be routing.
Your virtual appliance might have multiple NICs so this next cmdlet will allow you to select which one you want to configure:
$NicName = ((Get-AzureRmVM -ResourceGroupName $RgName -Name $VmName).NetworkInterfaceIDs).Split("/")[-1] | Out-GridView -Title "Select a NIC to configure forwarding ..." –PassThru
Then you’ll get the configuration of that NIC using the following line:
$NicConfig = Get-AzureRmNetworkInterface -ResourceGroupName $RgName -Name $NicName
And finally, you enable IP forwarding:
$NicConfig.EnableIPForwarding = $true $NicConfig | Set-AzureRmNetworkInterface
Make sure that you enable IP forwarding on every NIC in the virtual appliance that will be routing traffic for a subnet.