Getting a VM out the Azure Load Balancer pool

When it’s time for maintenance you need to take your VMs out of rotation in the Azure Load Balancer backend pool. If you’ve deployed your solution via the portal, a JSON Template or via ARM scripting, you know that there are many moving parts involved. There is no API specific for this and what you have to do is unbind the network interface card (NIC) from the backend address pool. Script wise, this is not a one-liner although not as complex as you might think at first.

Steps to remove a VM from the Load Balancer pool

First step is to find the NIC on the VM. Assuming your VM only have one NIC this is not that complicated. Once you have the NIC, you just update it and discard the binding to the load balancer.

In Azure CLI code this would be as below. You name the NIC and you pass in nothing for the parameter –lb-address-pool-ids.

azure network nic set -g resourceGroup -n nickname --lb-address-pool-ids

In PowerShell this is bit more complex as you have to nullify the property instead

$nic = Get-AzureRmNetworkInterface -ResourceGroupName $rgName -Name $nicName

$nic.IpConfigurations[0].LoadBalancerBackendAddressPools = $null

Set-AzureRmNetworkInterface -NetworkInterface $nic

Bear in mind that the CLI version expects a resource-id for it’s parameter value and not just the name. The resource-id is the long path containing the subscription-guid, etc.

Steps to add a VM to the Load Balancer pool

Once you are done with your maintenance of your VM it is time to put it back in the pool. This is basically no different from the above steps except this time we need to supply a value of the load balancer’s backend pool instead of nullifying it.

In Azure CLI on a Mac/Linux, this becomes a somewhat tricky task if we want to stick with using just a bash script. The CLI can emit JSON, which makes parsing it simpler, but bash has no build in JSON parser functionality, so for this I use jq (see refs for Github).

 # get vm nic id
nicID=$(azure vm show -g $resourceGroupName -n $vmName --json | jq '.networkProfile.networkInterfaces[0].id')
# remove double quotes at start/end
nicID="${nicID%\"}"
nicID="${nicID#\"}"
# get just the name and not the long resourceId
nicName=$(echo $nicID | cut -f9 -d '/')

# get id of LB BE pool
lbbeID=$(azure network lb address-pool list  -g $resourceGroupName -l $loadBalancerName --json | jq '.[0].id')
# remove double quotes at start/end
lbbeID="${lbbeID%\"}"
lbbeID="${lbbeID#\"}"

# add nic to lb
azure network nic set -g $resourceGroupName -n $nicName --lb-address-pool-ids $lbbeID

In PowerShell this is cleaner and means looking up the LoadBalancer and finding it’s backend address pool to the NIC.

$nic = Get-AzureRmNetworkInterface -ResourceGroupName $rgName -Name $nicName

$lb = Get-AzureRmLoadBalancer -Name $LoadBalancerName -ResourceGroupName $rgName

$nic.IpConfigurations[0].LoadBalancerBackendAddressPools = $lb.BackendAddressPools

Set-AzureRmNetworkInterface -NetworkInterface $nic

Putting it together

In my github repo, I’ve added small bash and PowerShell scripts that carries out the operation of adding and removing a VM from the load balancer.

Removing a VM script wise from the Load Balancer es-lb-remove

Adding the VM back to the Load Balancer pool

es-lb-add

References

JSON parser on Github
https://stedolan.github.io/jq/

Script Github repo
https://github.com/cljung/az-search-cluster