Azure Load Balancer Quickstart

Deploying a Load Balancer using ARM Templates

Introduction

This guide provides a step-by-step walkthrough on deploying an Azure Load Balancer and associated resources using an Azure Resource Manager (ARM) template. An Azure Load Balancer distributes incoming traffic across multiple virtual machines (VMs), enhancing application availability and responsiveness. ARM templates enable declarative deployment of your Azure infrastructure.

Note: This quickstart focuses on a basic internal load balancer setup for simplicity. Azure Load Balancer offers various configurations including public load balancers, network load balancers, and advanced health probe settings.

Prerequisites

Deployment Steps

We will use a pre-defined ARM template to deploy an internal load balancer, a virtual network, subnets, network interfaces, and virtual machines.

Step 1: Download the ARM Template

Download the ARM template and its parameters file from the Azure quickstart templates repository. You can also copy the content directly below.

ARM Template (azuredeploy.json)
{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "vmNamePrefix": {
            "type": "string",
            "defaultValue": "myVM",
            "metadata": {
                "description": "Prefix for names of all VMs deployed."
            }
        },
        "adminUsername": {
            "type": "string",
            "defaultValue": "azureuser",
            "metadata": {
                "description": "User name for the virtual machines."
            }
        },
        "adminPassword": {
            "type": "securestring",
            "metadata": {
                "description": "Password for the virtual machines."
            }
        },
        "loadBalancerName": {
            "type": "string",
            "defaultValue": "myInternalLoadBalancer",
            "metadata": {
                "description": "Name of the internal load balancer."
            }
        },
        "virtualNetworkName": {
            "type": "string",
            "defaultValue": "myVNet",
            "metadata": {
                "description": "Name of the virtual network."
            }
        },
        "subnetName": {
            "type": "string",
            "defaultValue": "mySubnet",
            "metadata": {
                "description": "Name of the subnet."
            }
        },
        "backendPoolName": {
            "type": "string",
            "defaultValue": "myBackendPool",
            "metadata": {
                "description": "Name of the backend address pool."
            }
        },
        "healthProbeName": {
            "type": "string",
            "defaultValue": "myHealthProbe",
            "metadata": {
                "description": "Name of the health probe."
            }
        },
        "loadBalancingRuleName": {
            "type": "string",
            "defaultValue": "myHTTPRule",
            "metadata": {
                "description": "Name of the load balancing rule."
            }
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Location for all resources."
            }
        },
        "vmCount": {
            "type": "int",
            "defaultValue": 2,
            "metadata": {
                "description": "Number of virtual machines to deploy."
            }
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Network/virtualNetworks",
            "apiVersion": "2020-11-01",
            "name": "[parameters('virtualNetworkName')]",
            "location": "[parameters('location')]",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "10.0.0.0/16"
                    ]
                },
                "subnets": [
                    {
                        "name": "[parameters('subnetName')]",
                        "properties": {
                            "addressPrefix": "10.0.0.0/24"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/loadBalancers",
            "apiVersion": "2020-11-01",
            "name": "[parameters('loadBalancerName')]",
            "location": "[parameters('location')]",
            "properties": {
                "frontendIpConfigurations": [
                    {
                        "name": "LoadBalancerFrontend",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
                            }
                        }
                    }
                ],
                "backendAddressPools": [
                    {
                        "name": "[parameters('backendPoolName')]"
                    }
                ],
                "healthProbes": [
                    {
                        "name": "[parameters('healthProbeName')]",
                        "properties": {
                            "protocol": "Http",
                            "port": 80,
                            "intervalInSeconds": 5,
                            "numberOfProbes": 2
                        }
                    }
                ],
                "loadBalancingRules": [
                    {
                        "name": "[parameters('loadBalancingRuleName')]",
                        "properties": {
                            "frontendIpConfiguration": {
                                "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', parameters('loadBalancerName'), 'LoadBalancerFrontend')]"
                            },
                            "backendAddressPool": {
                                "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('loadBalancerName'), parameters('backendPoolName'))]"
                            },
                            "probe": {
                                "id": "[resourceId('Microsoft.Network/loadBalancers/healthProbes', parameters('loadBalancerName'), parameters('healthProbeName'))]"
                            },
                            "protocol": "Tcp",
                            "frontendPort": 80,
                            "backendPort": 80,
                            "enableFloatingIP": false,
                            "idleTimeoutInMinutes": 4,
                            "loadDistribution": "Default"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2020-11-01",
            "name": "[concat(parameters('vmNamePrefix'), '-0')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
            ],
            "properties": {
                "hardwareProfile": {
                    "vmSize": "Standard_B1s"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "Canonical",
                        "offer": "0001-com-ubuntu-server-focal",
                        "version": "20.04.202307250"
                    },
                    "osDisk": {
                        "createOption": "FromImage",
                        "managedDisk": {
                            "storageAccountType": "Standard_LRS"
                        }
                    }
                },
                "osProfile": {
                    "computerName": "[concat(parameters('vmNamePrefix'), '-0')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]"
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmNamePrefix'), '-nic-', '0'))]",
                            "properties": {
                                "primary": true
                            }
                        }
                    ]
                }
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2020-11-01",
            "name": "[concat(parameters('vmNamePrefix'), '-nic-', '0')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]",
                "[resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancerName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
                            },
                            "loadBalancerBackendAddresses": [
                                {
                                    "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('loadBalancerName'), parameters('backendPoolName'))]"
                                }
                            ]
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Compute/virtualMachines",
            "apiVersion": "2020-11-01",
            "name": "[concat(parameters('vmNamePrefix'), '-1')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
            ],
            "properties": {
                "hardwareProfile": {
                    "vmSize": "Standard_B1s"
                },
                "storageProfile": {
                    "imageReference": {
                        "publisher": "Canonical",
                        "offer": "0001-com-ubuntu-server-focal",
                        "version": "20.04.202307250"
                    },
                    "osDisk": {
                        "createOption": "FromImage",
                        "managedDisk": {
                            "storageAccountType": "Standard_LRS"
                        }
                    }
                },
                "osProfile": {
                    "computerName": "[concat(parameters('vmNamePrefix'), '-1')]",
                    "adminUsername": "[parameters('adminUsername')]",
                    "adminPassword": "[parameters('adminPassword')]"
                },
                "networkProfile": {
                    "networkInterfaces": [
                        {
                            "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(parameters('vmNamePrefix'), '-nic-', '1'))]",
                            "properties": {
                                "primary": true
                            }
                        }
                    ]
                }
            }
        },
        {
            "type": "Microsoft.Network/networkInterfaces",
            "apiVersion": "2020-11-01",
            "name": "[concat(parameters('vmNamePrefix'), '-nic-', '1')]",
            "location": "[parameters('location')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]",
                "[resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancerName'))]"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetworkName'), parameters('subnetName'))]"
                            },
                            "loadBalancerBackendAddresses": [
                                {
                                    "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('loadBalancerName'), parameters('backendPoolName'))]"
                                }
                            ]
                        }
                    }
                ]
            }
        }
    ],
    "outputs": {
        "loadBalancerPrivateIP": {
            "type": "string",
            "value": "[reference(resourceId('Microsoft.Network/loadBalancers', parameters('loadBalancerName')), '2020-11-01').frontendIpConfigurations[0].properties.privateIpAddress]"
        }
    }
}
Parameters File (azuredeploy.parameters.json)
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "adminPassword": {
            "value": "YourStrongPassword123!"
        },
        "vmNamePrefix": {
            "value": "myLBVM"
        },
        "loadBalancerName": {
            "value": "myQuickstartLB"
        },
        "virtualNetworkName": {
            "value": "myQuickstartVNet"
        },
        "subnetName": {
            "value": "myQuickstartSubnet"
        },
        "backendPoolName": {
            "value": "myQuickstartBackendPool"
        },
        "healthProbeName": {
            "value": "myQuickstartHealthProbe"
        },
        "loadBalancingRuleName": {
            "value": "myQuickstartHTTPRule"
        },
        "location": {
            "value": "[resourceGroup().location]"
        },
        "vmCount": {
            "value": 2
        }
    }
}

Important: Replace "YourStrongPassword123!" in the azuredeploy.parameters.json file with a strong password for your virtual machines.

Step 2: Deploy the ARM Template

Use the Azure CLI to deploy the ARM template to your resource group.

az deployment group create --resource-group MyLoadBalancerResourceGroup --template-file azuredeploy.json --parameters azuredeploy.parameters.json

Replace MyLoadBalancerResourceGroup with the name of your resource group.

Tip: You can also deploy using Azure PowerShell with the New-AzResourceGroupDeployment cmdlet.

Step 3: Obtain the Load Balancer's Private IP Address

After the deployment is complete, you can retrieve the private IP address assigned to the load balancer's frontend configuration.

az deployment group show --resource-group MyLoadBalancerResourceGroup --name azuredeploy --query properties.outputs.loadBalancerPrivateIP.value -o tsv

Note down this IP address, as you will use it for verification.

Verification

To verify that the load balancer is working correctly, you can attempt to access the virtual machines through its private IP address. Since this is an internal load balancer, you would typically do this from another VM within the same virtual network.

  1. SSH into one of the backend VMs.
  2. Install a simple web server (e.g., Nginx or Apache) and ensure it's listening on port 80.
  3. From another machine (or VM) within the same VNet, use a tool like curl to access the load balancer's private IP address: curl <LOAD_BALANCER_PRIVATE_IP>
  4. You should receive a response from one of the web servers. Repeatedly making requests should show responses from different backend VMs (if they serve unique content or headers indicating their identity).

Important: For this verification, ensure that Network Security Groups (NSGs) allow traffic on port 80 to your backend VMs and to the load balancer's frontend IP address.

Cleanup

To avoid ongoing charges, you should delete the resources created in this quickstart when you are finished.

You can delete the entire resource group, which will remove all the resources deployed by the ARM template.

az group delete --name MyLoadBalancerResourceGroup --yes --no-wait

This command will delete the resource group and all its contents. The --no-wait flag allows the operation to complete in the background.