Project: Azure Load Balancers

Learn how to configure an Azure Load Balancer in this lesson.

Azure load balancer

An Azure load balancer consists of three components: the frontend IP address configuration, the backend IP pool, and the load balancer itself. You’ll see that each of these components needs a name in the below given code snippet.

  • Frontend IP address configuration called NoBSAzureLb-LbFeIP.

  • Backend IP address pool called NoBSAzureLb-AddrPool.

  • An Azure Load Balancer called NoBSAzureLb-Lb.

Note the names used here are not mandatory. You may use any name you’d like.

Each of these components comes together to create a Basic load balancer. The command below could create a Standard SKU too, which provides more advanced functionality, but it is not needed for this project.

$lbName = "$projectName-Lb"
$lbFeIp = "$projectName-LbFeIp"
$lbAddrPool = "$projectName-AddrPool"
az network lb create `
    --name $lbName `
    --public-ip-address $pipName `
    --sku Basic `
    --frontend-ip-name $lbFeIp `
    --backend-pool-name $lbAddrPool

Health probe

When the project is complete, the load balancer needs a place to send web traffic to. For this project, that traffic will go to a VM availability set with three VMs. To ensure the website remains functional at all times, the load balancer must know how to determine if a VM is functional or not. The load balancer needs to know if each VM is “healthy” or serving up a web page.

To ensure the load balancer knows the status of all of the VMs, it uses a health probe.

Since the load balancer is set to the Basic SKU, you have two options: TCP or HTTP. The Standard SKU provides a HTTPS health probe. The following code snippet is using the HTTP health probe (protocol) on TCP port 80 (port), probing the root of the web directory (/).

$lbProbeName = "$lbName-HealthProbe"
az network lb probe create `
    --lb-name $lbName `
    --name $lbProbeName `
    --port 80 `
    --protocol http `
    --path /

Once operational, the health probe above will continually check each VM to ensure the website is listening on port 80 and returns an HTTP 200 request.

Load balancer rules

As is, the load balancer doesn’t know where to send traffic to. Let’s fix that with a load balancer rule. The load balancer rule is a “mapping” that “maps” a frontend IP address and port to a backend port with a health probe.

The following code snippet is creating a rule to:

  • Direct all traffic coming into the frontend IP configuration (frontend-ip-name) on TCP port 80 (protocol and frontend-port).
  • An available VM’s TCP port 80 (protocol and backend-port).
  • First ensure the VM is healthy by checking the status of the health probe (probe-name).
az network lb rule create `
    --lb-name $lbName `
    --name "$lbName-RuleWeb" `
    --protocol tcp `
    --frontend-port 80 `
    --backend-port 80 `
    --frontend-ip-name $lbFeIp `
    --backend-pool-name $lbAddrPool `
    --probe-name $lbProbeName

Once created, the load balancer now knows how to handle web traffic coming in via the public IP.

VM availability set

The load balancer currently knows how to handle web traffic, but it has nothing to send it to. Let’s now create a target serving up a simple website using some VMs.

To create the VM availability set, the VMs, their NICs, and to install IIS, you should run the following code.

$availabilitySetName = "$projectName-VmAvailSet"
az vm availability-set create --name $availabilitySetName

$obj = [pscustomobject]@{
    "fileUris"         = @("https://raw.githubusercontent.com/NoBSDevOps/BookResources/master/Part%20I%3A%20Tools/Azure%20Load%20Balancers/Install-IIS.ps1")
    "commandToExecute" = "powershell.exe .\Install-IIS.ps1"
}
$obj | ConvertTo-Json | Set-Content './iis_custom_script_settings.json'

0..2 | ForEach-Object {
	## Assign the variables here to reuse
    $vmName = "$projectName-$_"
    $nicName = "$vmName-Nic"
    
    # Create the VM's NIC assigning it to all of the resources created earlier
    az network nic create `
        --name $nicName `
        --vnet-name $vNetName --subnet $subNetName `
        --network-security-group $nsgName --lb-name $lbName `
        --lb-address-pools $lbAddrPool

    <# Create the VM and:
        - Assign it to an availability set
        - Using the latest Windows Server Datacenter 2019 image
        - Assign the NIC just created
        - Define an arbitrary size (Standard_DS1_v2) not required. Define based on expected load
        - VM admin and password for the local administrator account
	#>
    az vm create `
        --name $vmName `
        --availability-set $availabilitySetName `
        --image MicrosoftWindowsServer:WindowsServer:2019-Datacenter:latest `
        --nics $nicName `
        --size 'Standard_DS1_v2' `
        --admin-password 'I like azure.' `
        --admin-username 'NoBS'
    ## Install the Windows custom script extension on the VM telling it to download
    ## the Install-IIS.ps1 script
    az vm extension set `
        --vm-name $vmName --name CustomScriptExtension `
        --publisher Microsoft.Compute `
        --settings './iis_custom_script_settings.json'
}

The Install-IIS.ps1 script referenced in the code snippet installs IIS via Install-WindowsFeature as shown below.

$ProgressPreference = 'SilentlyContinue'
Install-WindowsFeature -Name 'Web-Server'

These steps will take a few minutes to run but by the time it’s done, you’ll have a complete project!

Testing the load balancer

When you get control of the PowerShell console again and you see no ugly red text, all components are complete and it’s time to test!

To perform a quick test of this project, first find the IP of the public IP address created earlier. Using az network public-ip list and a little PowerShell JSON conversion, you can find it.

(az network public-ip list | ConvertFrom-Json).ipAddress

Once you know the public IP, now open a browser and navigate to the IP at http:\[public ip].

For fun, stop one or two of the VMs created earlier. If all works as designed, you should notice the sample website isn’t affected at all!

Cleaning up

Once you’ve confirmed (hopefully) that the sample web site is active and remains that way even if a VM dies, don’t forget to clean up the resources. You will be charged if you leave these resources on!

With the single Azure CLI command below, you can initiate the removal of the entire resource group. Using the no-wait argument means you won’t have to wait. The process may take up to 10-15 minutes.

az group delete --yes --no-wait

Project conclusion

You’re done! If you’ve stuck with the entire project section in this chapter, nice job! That was a lot of Azure CLI wielding you’ve done. It’s important to understand the concepts and why some commands do what they do and what your options are.

Clean up the resource group and go through it again, experiment, see what options you have, and investigate what else is possible when setting up a load-balanced website!

Try it yourself!

Press the Run button and practice all these commands yourself after providing the environment variables.

Get hands-on with 1200+ tech skills courses.