Azure Proactive Resiliency Library v2
Tools Glossary GitHub GitHub Issues Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

loadBalancers

Summary

RecommendationImpactCategoryAutomation AvailableIn Azure Advisor
Use Standard Load Balancer SKUHighHigh AvailabilityYesNo
Ensure the Backend Pool contains at least two instancesHighHigh AvailabilityYesNo
Use NAT Gateway instead of Outbound Rules for Production WorkloadsMediumHigh AvailabilityYesNo
Ensure Standard Load Balancer is zone-redundantHighHigh AvailabilityYesNo
Use Health Probes to detect backend instances availabilityHighMonitoring and AlertingYesNo

Details


Use Standard Load Balancer SKU

Impact:  High Category:  High Availability

APRL GUID:  38c3bca1-97a1-eb42-8cd3-838b243f35ba

Description:

Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA.

Potential Benefits:

Enhanced reliability and SLA support
Learn More:
Reliability and Azure Load Balancer
Resiliency checklist for specific Azure services- Azure Load Balancer

ARG Query:

Click the Azure Resource Graph tab to view the query

// Azure Resource Graph Query
// Find all LoadBalancers using Basic SKU
resources
| where type =~ 'Microsoft.Network/loadBalancers'
| where sku.name == 'Basic'
| project recommendationId = "38c3bca1-97a1-eb42-8cd3-838b243f35ba", name, id, tags, Param1=strcat("sku-tier: basic")



Ensure the Backend Pool contains at least two instances

Impact:  High Category:  High Availability

APRL GUID:  6d82d042-6d61-ad49-86f0-6a5455398081

Description:

Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Pairing with Virtual Machine Scale Sets is advised for optimal scale building.

Potential Benefits:

Enhances reliability and scalability
Learn More:
Resiliency checklist for specific Azure services- Azure Load Balancer

ARG Query:

Click the Azure Resource Graph tab to view the query

// Azure Resource Graph Query
// Find all LoadBalancers which only have 1 backend pool defined or only 1 VM in the backend pool
resources
| where type =~ 'Microsoft.Network/loadBalancers'
| extend bep = properties.backendAddressPools
| extend BackEndPools = array_length(bep)
| where BackEndPools == 0
| project recommendationId = "6d82d042-6d61-ad49-86f0-6a5455398081", name, id, Param1="backendPools", Param2=toint(0), tags
| union (resources
  | where type =~ 'Microsoft.Network/loadBalancers'
  | where sku.name == "Standard"
  | extend bep = properties.backendAddressPools
  | extend BackEndPools = toint(array_length(bep))
  | mv-expand bip = properties.backendAddressPools
  | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses)
  | where toint(BackendAddresses) <= 1
  | project recommendationId = "6d82d042-6d61-ad49-86f0-6a5455398081", name, id, tags, Param1="backendAddresses", Param2=toint(BackendAddresses))
| union (
  resources
  | where type =~ 'Microsoft.Network/loadBalancers'
  | where sku.name == "Basic"
  | mv-expand properties.backendAddressPools
  | extend backendPoolId = properties_backendAddressPools.id
  | project id, name, tags, tostring(backendPoolId), recommendationId = "6d82d042-6d61-ad49-86f0-6a5455398081", Param1="BackEndPools"
  | join kind = leftouter (
  resources
  | where type =~ "Microsoft.Network/networkInterfaces"
  | mv-expand properties.ipConfigurations
  | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools
  | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id)
  | summarize poolMembers = count() by backendPoolId
  | project tostring(backendPoolId), poolMembers ) on backendPoolId
  | where toint(poolMembers) <= 1
  | extend BackendAddresses = poolMembers
  | project id, name, tags, recommendationId, Param1="backendAddresses", Param2=toint(BackendAddresses))


Use NAT Gateway instead of Outbound Rules for Production Workloads

Impact:  Medium Category:  High Availability

APRL GUID:  8d319a05-677b-944f-b9b4-ca0fb42e883c

Description:

Outbound rules for Standard Public Load Balancer involve manual port allocation for backend pools, limiting scalability and risk of SNAT port exhaustion. NAT Gateway is recommended for its dynamic scaling and secure internet connectivity.

Potential Benefits:

Enhanced scalability and reliability
Learn More:
Resiliency checklist for specific Azure services- Azure Load Balancer

ARG Query:

Click the Azure Resource Graph tab to view the query

// Azure Resource Graph Query
// Find all LoadBalancers with Outbound rules configured
resources
| where type =~ 'Microsoft.Network/loadBalancers'
| extend outboundRules = array_length(properties.outboundRules)
| where outboundRules > 0
| project recommendationId = "8d319a05-677b-944f-b9b4-ca0fb42e883c", name, id, tags, Param1 = "outboundRules: >=1"



Ensure Standard Load Balancer is zone-redundant

Impact:  High Category:  High Availability

APRL GUID:  621dbc78-3745-4d32-8eac-9e65b27b7512

Description:

In regions with Availability Zones, assigning a zone-redundant frontend IP to a Standard Load Balancer ensures continuous traffic distribution even if one availability zone fails, provided other healthy zones and backend instances are available to receive the traffic.

Potential Benefits:

Enhances uptime and resilience
Learn More:
Load Balancer and Availability Zones

ARG Query:

Click the Azure Resource Graph tab to view the query

// Azure Resource Graph Query
// Find all LoadBalancers with with regional or zonal public IP Addresses
resources
| where type == "microsoft.network/loadbalancers"
| where location in~ ("australiaeast", "brazilsouth", "canadacentral", "centralindia", "centralus", "eastasia", "eastus", "eastus2", "francecentral", "germanywestcentral", "israelcentral", "italynorth", "japaneast", "japanwest", "koreacentral", "mexicocentral", "newzealandnorth", "northeurope", "norwayeast", "polandcentral", "qatarcentral", "southafricanorth", "southcentralus", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", "westeurope", "westus2", "westus3", "usgovvirginia", "chinanorth3")
| where tolower(sku.name) != 'basic'
| mv-expand feIPconfigs = properties.frontendIPConfigurations
| extend
    feConfigName = (feIPconfigs.name),
    PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id),
    PrivateIPZones = feIPconfigs.zones,
    PIPid = toupper(feIPconfigs.properties.publicIPAddress.id),
    JoinID = toupper(id)
| where isnotempty(PrivateSubnetId)
| where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2
| project name, feConfigName, id
| union (resources
    | where type == "microsoft.network/loadbalancers"
    | where location in~ ("australiaeast", "brazilsouth", "canadacentral", "centralindia", "centralus", "eastasia", "eastus", "eastus2", "francecentral", "germanywestcentral", "israelcentral", "italynorth", "japaneast", "japanwest", "koreacentral", "mexicocentral", "newzealandnorth", "northeurope", "norwayeast", "polandcentral", "qatarcentral", "southafricanorth", "southcentralus", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", "westeurope", "westus2", "westus3", "usgovvirginia", "chinanorth3")
    | where tolower(sku.name) != 'basic'
    | mv-expand feIPconfigs = properties.frontendIPConfigurations
    | extend
        feConfigName = (feIPconfigs.name),
        PIPid = toupper(feIPconfigs.properties.publicIPAddress.id),
        JoinID = toupper(id)
    | where isnotempty(PIPid)
    | join kind=innerunique (
        resources
        | where type == "microsoft.network/publicipaddresses"
        | where location in~ ("australiaeast", "brazilsouth", "canadacentral", "centralindia", "centralus", "eastasia", "eastus", "eastus2", "francecentral", "germanywestcentral", "israelcentral", "italynorth", "japaneast", "japanwest", "koreacentral", "mexicocentral", "newzealandnorth", "northeurope", "norwayeast", "polandcentral", "qatarcentral", "southafricanorth", "southcentralus", "southeastasia", "spaincentral", "swedencentral", "switzerlandnorth", "uaenorth", "uksouth", "westeurope", "westus2", "westus3", "usgovvirginia", "chinanorth3")
        | where isnull(zones) or array_length(zones) < 2
        | extend
            LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))),
            InnerID = toupper(id)
    ) on $left.PIPid == $right.InnerID)
| project recommendationId = "621dbc78-3745-4d32-8eac-9e65b27b7512", name, id, tags, param1="Zones: No Zone or Zonal", param2=strcat("Frontend IP Configuration:", " ", feConfigName)



Use Health Probes to detect backend instances availability

Impact:  High Category:  Monitoring and Alerting

APRL GUID:  e5f5fcea-f925-4578-8599-9a391e888a60

Description:

Health probes are used by Azure Load Balancers to determine the status of backend endpoints. Using custom health probes that are aligned with vendor recommendations enhances understanding of backend availability and facilitates monitoring of backend services for any impact.

Potential Benefits:

Ensures backend uptime monitoring.
Learn More:
Load Balancer Health Probe Overview

ARG Query:

Click the Azure Resource Graph tab to view the query

// Azure Resource Graph Query
// List the load balancers which don't have health probe configured
resources
| where type =~ "microsoft.network/loadbalancers"
| where array_length(properties.probes) == 0
| project recommendationId="e5f5fcea-f925-4578-8599-9a391e888a60", name, id, tags, param1="customHealthProbeUsed: false"