Step-by-Step Guide: Application layer (OSI layer 7) load balancing with Azure Application Gateway (PowerShell Guide)

In my previous blog posts, I explained about two types of Azure solution to load balance web traffic.

Azure Traffic Manager – If you are looking for DNS level load balancing which can distribute traffic to global endpoints, Azure traffic manager will be the product to look at. More info about deployment can be found on

Azure Load Balancer – Azure load balancer works in layer 4 (transport layer) and can distribute network traffic to endpoints in the same Azure region. It can use to distribute internet traffic as well as internal traffic. More info about deployment can be found on

However, if you looking for Layer 7 (Application Layer) load balancing solution, Azure Application Gateway is the answer. Azure Application Gateway has the following features,

• Secure Sockets Layer (SSL/TLS) termination
• Autoscaling
• Zone redundancy
• Static VIP
• Web Application Firewall
• Ingress Controller for AKS
• URL-based routing
• Multiple-site hosting
• Redirection
• Session affinity
• Websocket and HTTP/2 traffic
• Connection draining
• Custom error pages
• Rewrite HTTP headers
• Sizing

More info about these features are available on

In this demo, I am going to show how we can setup URL-based routing using Azure Application Gateway.

To do that I will need to do the following tasks,

1. Setup new resource group
2. Create Virtual Networks
3. AG IP and frontend port configuration
4. Create Backend pool
5. Create listener and AG routing rule
6. Create Azure Application Gateway
7. Add Backend pools for videos and images
8. Add frontend port for the pool
9. Create Backend Listener
10. Create URL path map
11. Create routing rule
12. Create virtual machines
13. Add Web Content
14. Testing

For the configuration process, I will be using Azure PowerShell. Therefore, please make sure you have Azure PowerShell module installed. More info about it can find under

Setup new resource group

Launch PowerShell console and connect to Azure using Connect-AzAccount

Then create a new resource group using,

New-AzResourceGroup -Name REBELRG1 -Location “East US”

In the above, REBELRG1 is the resource group name and East US is the resource group location.

Create Virtual Networks

In this demo, I am going to use two back end servers. Before VM setup, let’s go ahead and create a new virtual network in REBELRG1 resource group.

$vmsubnet = New-AzVirtualNetworkSubnetConfig -Name vmsubnet -AddressPrefix “”
$agsubnet = New-AzVirtualNetworkSubnetConfig -Name agsubnet -AddressPrefix “”
New-AzVirtualNetwork -Name REBELVN1 -ResourceGroupName REBELRG1 -Location “East US” -AddressPrefix “” -Subnet $vmsubnet, $agsubnet

In the above, REBELVN1 is the new virtual network name. It has address space. It also has a new subnet (vmsubnet) for virtual machines and subnet (agsubnet) for the application gateway.

Create new public IP address

We require public ip address for Azure Application gateway. This will be the external contact point for the gateway. To create that,

New-AzPublicIpAddress -ResourceGroupName REBELRG1 -Location “East US” -Name REBELPublicIP01 -AllocationMethod Static -Sku Standard

In the above, we are creating a public IP address called REBELPublicIP01 with standard SKU.

AG IP and frontend port configuration

The next step of the configuration is to assign AG gateway subnet and public IP address to Application gateway and create frontend port to use for external connectivity. To do that,

$net = Get-AzVirtualNetwork -ResourceGroupName REBELRG1 -Name REBELVN1

The above commands will grab the subnet information from the virtual network REBELVN1.

$rpublicip = Get-AzPublicIpAddress -ResourceGroupName REBELRG1 -Name REBELPublicIP01

Then I went ahead and gather information about the public IP address we created in a previous step.
The next step is to assign the subnet info to AG configuration.

$agipconfig = New-AzApplicationGatewayIPConfiguration -Name REBELAGIPconf -Subnet $subnet

After, we need to assign public ip to gateway’s front-end configuration.

$frontipconf = New-AzApplicationGatewayFrontendIPConfig -Name REBELAGfrontconf -PublicIPAddress $rpublicip

In this demo, we will be connecting to web services via TCP port 80. We need to add it to the AG frontend configuration.

$frontport = New-AzApplicationGatewayFrontendPort -Name REBELAGFrontendP -Port 80

Create Backend pool

The next part of the configuration is to set up a back end pool for the new Azure application gateway with relevant settings.

$backendpool = New-AzApplicationGatewayBackendAddressPool -Name REBELAGBackendPool
$backendpoolconf = New-AzApplicationGatewayBackendHttpSetting -Name REBELAGBackendPoolconf -Port 80 -Protocol Http -CookieBasedAffinity Enabled -RequestTimeout 120

In the above, we create a backend pool called REBELAGBackendPool with cookie-based affinity and request time out 120.

Create listener and AG routing rule

Application gateway use listeners to route traffic to backend pool. So, we also need to create one for the new AG.

$rebellistener = New-AzApplicationGatewayHttpListener -Name REBLEAGListener -Protocol Http -FrontendIPConfiguration $frontipconf -FrontendPort $frontport

Then we also need to setup rule to say how the incoming traffic will handled.

$routingrule = New-AzApplicationGatewayRequestRoutingRule -Name REBELAGrule1 -RuleType Basic -HttpListener $rebellistener -BackendAddressPool $backendpool -BackendHttpSettings $backendpoolconf

Create Azure Application Gateway

Now we have all the required configuration settings to create Azure application gateway. Let’s go ahead and create it.

$agsku = New-AzApplicationGatewaySku -Name Standard_v2 -Tier Standard_v2 -Capacity 2

$appgw = New-AzApplicationGateway -Name REBELAG1 -ResourceGroupName REBELRG1 -Location “East US” -BackendAddressPools $backendpool -BackendHttpSettingsCollection $backendpoolconf -FrontendIpConfigurations $frontipconf -GatewayIpConfigurations $agipconfig -FrontendPorts $frontport -HttpListeners $rebellistener -RequestRoutingRules $routingrule -Sku $agsku

Add Backend pools for videos and images

In this demo I am going to use two back end pools for music and videos. This way I can route traffic to different pools. To do this,

Add-AzApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name musicBackendPool
Add-AzApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name videoBackendPool

Add frontend port for the pool

As the next step of the configuration, we need to add front end port to the pool. To do that we can use,

Add-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name fport -Port 8080

After that, we need to apply above changes to the application gateway using,

Set-AzApplicationGateway -ApplicationGateway $appgw

Add backend listener

The next step of the configuration is to add a new back end listener. This is required for traffic routing from AG to relevant pools.

$beport = Get-AzApplicationGatewayFrontendPort -ApplicationGateway $appgw -Name fport
$fipconf = Get-AzApplicationGatewayFrontendIPConfig -ApplicationGateway $appgw

Add-AzApplicationGatewayHttpListener -ApplicationGateway $appgw -Name beListener -Protocol Http -FrontendIPConfiguration $fipconf -FrontendPort $beport

At the end we need to apply the configuration to AG using,

Set-AzApplicationGateway -ApplicationGateway $appgw

Create URL Path map

Now we need to create URL map so when user try to access http://agip/music , it is routed to music pool and when user try http://agip/video it is routed to video pool.

$poolconf = Get-AzApplicationGatewayBackendHttpSetting -ApplicationGateway $appgw -Name REBELAGBackendPoolconf
$musicpool = Get-AzApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name musicBackendPool
$videopool = Get-AzApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name videoBackendPool
$defaultpool = Get-AzApplicationGatewayBackendAddressPool -ApplicationGateway $appgw -Name REBELAGBackendPool
$musicrule = New-AzApplicationGatewayPathRuleConfig -Name musicpathrule -Paths “/music/*” -BackendAddressPool $musicpool -BackendHttpSettings $poolconf
$videorule = New-AzApplicationGatewayPathRuleConfig -Name videopathrule -Paths “/video/*” -BackendAddressPool $videopool -BackendHttpSettings $poolconf

Then we should create URL path map configuration using,

Add-AzApplicationGatewayUrlPathMapConfig -ApplicationGateway $appgw -Name urlpath -PathRules $musicrule, $videorule -DefaultBackendAddressPool $defaultpool -DefaultBackendHttpSettings $poolconf

After that we apply configuration to AG using,

Set-AzApplicationGateway -ApplicationGateway $appgw

Create routing rule

We need routing rule to point incoming traffic to relevant pools.

$backendlistener = Get-AzApplicationGatewayHttpListener -ApplicationGateway $appgw -Name beListener
$urlmap = Get-AzApplicationGatewayUrlPathMapConfig -ApplicationGateway $appgw -Name urlpath

Add-AzApplicationGatewayRequestRoutingRule -ApplicationGateway $appgw -Name routingrule -RuleType PathBasedRouting -HttpListener $backendlistener -UrlPathMap $urlmap

After that we should apply the configuration to AG using,

Set-AzApplicationGateway -ApplicationGateway $appgw

Create virtual machines

Now we have a working AG in place. The next step of the configuration is to create virtual machines in scale set so we can test it.
In this demo I am going to create 3 scale sets and add two virtual machines to each.

$net = Get-AzVirtualNetwork -ResourceGroupName REBELRG1 -Name REBELVN1
$appgw = Get-AzApplicationGateway -ResourceGroupName REBELRG1 -Name REBELAG1
$backendPool = Get-AzApplicationGatewayBackendAddressPool -Name REBELAGBackendPool -ApplicationGateway $appgw
$music = Get-AzApplicationGatewayBackendAddressPool -Name musicBackendPool -ApplicationGateway $appgw
$video = Get-AzApplicationGatewayBackendAddressPool -Name videoBackendPool -ApplicationGateway $appgw

for ($i=1; $i -le 3; $i++)
if ($i -eq 1)
$poolId = $backendPool.Id
if ($i -eq 2)
$poolId = $music.Id
if ($i -eq 3)
$poolId = $video.Id

$ipconfig = New-AzVmssIpConfig -Name REBELVMIPconf -SubnetId $net.Subnets[0].Id -ApplicationGatewayBackendAddressPoolsId $poolId

$vmssConfig = New-AzVmssConfig -Location eastus -SkuCapacity 2 -SkuName Standard_DS2 -UpgradePolicyMode Automatic
Set-AzVmssStorageProfile $vmssConfig -ImageReferencePublisher MicrosoftWindowsServer -ImageReferenceOffer WindowsServer -ImageReferenceSku 2016-Datacenter -ImageReferenceVersion latest -OsDiskCreateOption FromImage
Set-AzVmssOsProfile $vmssConfig -AdminUsername dfrancis -AdminPassword “WhitEpanda!” -ComputerNamePrefix REBELVMM$i
Add-AzVmssNetworkInterfaceConfiguration -VirtualMachineScaleSet $vmssConfig -Name REBELvmssconfig$i -Primary $true -IPConfiguration $ipconfig

New-AzVmss -ResourceGroupName REBELRG1 -Name REBELVMSS$i -VirtualMachineScaleSet $vmssConfig

Add web content

The next step of the configuration is to install IIS and push web content to instances running on virtual machine scale set.
Before we do that, we need a configuration file created and upload it to github. I have created with the following configuration.

Add-WindowsFeature Web-Server
Remove-item C:\inetpub\wwwroot\iisstart.htm
Add-Content -Path “C:\inetpub\wwwroot\Default.htm” -Value $($env:computername)
New-Item -ItemType directory -Path “C:\inetpub\wwwroot\music”
New-Item -ItemType directory -Path “C:\inetpub\wwwroot\video”
$musicvalue = “Music: ” + $($env:computername)
Add-Content -Path “C:\inetpub\wwwroot\music\test.htm” -Value $musicvalue
$videovalue = “Video: ” + $($env:computername)
Add-Content -Path “C:\inetpub\wwwroot\video\test.htm” -Value $videovalue

Then I am using it to install iis and push content to VM scale set.

$config = @{ “fileUris” = (,”″);
“commandToExecute” = “powershell -ExecutionPolicy Unrestricted -File agsetup.ps1” }

for ($i=1; $i -le 3; $i++)
$vmscaleset = Get-AzVmss -ResourceGroupName REBELRG1 -VMScaleSetName REBELVMSS$i
Add-AzVmssExtension -VirtualMachineScaleSet $vmscaleset -Name “script” -Publisher “Microsoft.Compute” -Type “CustomScriptExtension” -TypeHandlerVersion 1.8 -Setting $config

Update-AzVmss -ResourceGroupName REBELRG1 -Name REBELVMSS$i -VirtualMachineScaleSet $vmscaleset


This completes the configuration process of the Application Gateway. Now its time for testing. To connect from external first we need to find the external IP of the Application gateway. We can find it using,

Get-AzPublicIpAddress -ResourceGroupName REBELRG1

Now we know the frontend IP address. Let’s check the default pool first using,

as expected, it is loading from an instance running on REBELVMSS1 scale set.

Then let’s go ahead and test the URL for music on

As expected, it is loading from REBELVMSS2 scale set.

As of the last test, let’s try URL for video page using

Again, as expected it is loading from REBELVMSS3 scale set.

As we can see the different URLs are routed to different server pools by Application gateway.

I hope you now have a better understanding of how application gateway works and how we can use it for layer 7 load balancing. This marks the end of this blog post. If you have any further questions about this feel free to contact me on also follow me on twitter @rebeladm to get updates about new blog posts.