From ffab4758db1a736cc2a7c496c35bf904d0ad0252 Mon Sep 17 00:00:00 2001 From: Bernie White Date: Thu, 11 Apr 2024 09:03:59 +1000 Subject: [PATCH] Updates to LB rule docs (#2821) --- .github/workflows/docs.yaml | 1 + docs/en/rules/Azure.LB.Probe.md | 208 +++++++++++++++++++++++++- docs/en/rules/Azure.LB.StandardSKU.md | 66 ++++---- docs/examples-vnet.bicep | 74 +++++++++ docs/examples-vnet.json | 79 +++++++++- 5 files changed, 389 insertions(+), 39 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index fa2f98c5a9e..8e65ddab06a 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -67,6 +67,7 @@ jobs: - name: Push content run: | cd site/ + git config advice.addIgnoredFile false git config user.name github-actions git config user.email '41898282+github-actions[bot]@users.noreply.github.com' git add * diff --git a/docs/en/rules/Azure.LB.Probe.md b/docs/en/rules/Azure.LB.Probe.md index 0f433aae1fd..65963061de8 100644 --- a/docs/en/rules/Azure.LB.Probe.md +++ b/docs/en/rules/Azure.LB.Probe.md @@ -1,4 +1,5 @@ --- +reviewed: 2024-04-11 severity: Important pillar: Reliability category: RE:05 Redundancy @@ -6,7 +7,7 @@ resource: Load Balancer online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.LB.Probe/ --- -# Use specific load balancer probe +# Use a specific load balancer probe ## SYNOPSIS @@ -14,15 +15,218 @@ Use a specific probe for web protocols. ## DESCRIPTION -A load balancer probe can be configured as TCP/ HTTP or HTTPS. +A load balancer is an Azure service that distributes traffic among instances of a service in a backend pool (such as VMs). +Load balancers route traffic to instances in the backend pool based on configured rules. + +In additional to routing traffic, load balancers can also monitor the health of backend instances with a health probe. +Monitoring the health of backend instances allows the load balancer to route traffic towards health instances. +For example, if one instance is unavailable, the load balancer can route traffic to another instance that is available. + +To monitor the health of backend instances, the load balancer sends periodic requests and checks the response from the backend. +Azure Load Balancer supports health probes for TCP, HTTP, and HTTPS. + +If your backend is communicating over HTTP or HTTPS, you should: + +- Use HTTP/ HTTPS probes — instead of a TCP port. + For example, if a web server process is running it may not be able to respond to a TCP probe. + However, that does not indicate that the application is working correctly, as it could be returning a `5XX` error. + Using HTTP/ HTTPS probes allows you to check for a HTTP 200 status code. +- Use a dedicated health check endpoint — such as `/health` or `/healthz` for health probes. + Commonly the main landing page of an application `/` is not a good health check endpoint. + By design, it may only serve static content and not execute any application logic, such as a login page. ## RECOMMENDATION Consider using a dedicated health check endpoint for HTTP or HTTPS health probes. +## EXAMPLES + +### Configure with Azure template + +To deploy load balancers that pass this rule: + +- Configure HTTP or HTTPS based probes on ports that commonly use HTTP or HTTPS protocols. + - Set the `properties.probes[*]` property to include a probe with the following properties: + - `properties.probes[*].properties.protocol` set to `HTTPS`. + - `properties.probes[*].properties.requestPath` set to `/health`. + +For example: + +```json +{ + "type": "Microsoft.Network/loadBalancers", + "apiVersion": "2023-09-01", + "name": "[parameters('lbName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "frontend1", + "properties": { + "privateIPAddressVersion": "IPv4", + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), 'GatewaySubnet')]" + } + }, + "zones": [ + "2", + "3", + "1" + ] + } + ], + "backendAddressPools": [ + { + "name": "backend1" + } + ], + "probes": [ + { + "name": "https", + "properties": { + "protocol": "HTTPS", + "port": 443, + "requestPath": "/health", + "intervalInSeconds": 5, + "numberOfProbes": 1 + } + } + ], + "loadBalancingRules": [ + { + "name": "https", + "properties": { + "frontendIPConfiguration": { + "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', parameters('lbName'), 'frontend1')]" + }, + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 4, + "protocol": "TCP", + "loadDistribution": "Default", + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', parameters('lbName'), 'https')]" + }, + "disableOutboundSnat": true, + "enableTcpReset": false, + "backendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('lbName'), 'backend1')]" + } + ] + } + } + ], + "inboundNatRules": [], + "outboundRules": [] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), 'GatewaySubnet')]" + ] +} +``` + +### Configure with Bicep + +To deploy load balancers that pass this rule: + +- Configure HTTP or HTTPS based probes on ports that commonly use HTTP or HTTPS protocols. + - Set the `properties.probes[*]` property to include a probe with the following properties: + - `properties.probes[*].properties.protocol` set to `HTTPS`. + - `properties.probes[*].properties.requestPath` set to `/health`. + +For example: + +```bicep +resource https_lb 'Microsoft.Network/loadBalancers@2023-09-01' = { + name: lbName + location: location + sku: { + name: 'Standard' + } + properties: { + frontendIPConfigurations: [ + { + name: 'frontend1' + properties: { + privateIPAddressVersion: 'IPv4' + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: subnet01.id + } + } + zones: [ + '2' + '3' + '1' + ] + } + ] + backendAddressPools: [ + { + name: 'backend1' + } + ] + probes: [ + { + name: 'https' + properties: { + protocol: 'HTTPS' + port: 443 + requestPath: '/health' + intervalInSeconds: 5 + numberOfProbes: 1 + } + } + ] + loadBalancingRules: [ + { + name: 'https' + properties: { + frontendIPConfiguration: { + id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', lbName, 'frontend1') + } + frontendPort: 443 + backendPort: 443 + enableFloatingIP: false + idleTimeoutInMinutes: 4 + protocol: 'TCP' + loadDistribution: 'Default' + probe: { + id: resourceId('Microsoft.Network/loadBalancers/probes', lbName, 'https') + } + disableOutboundSnat: true + enableTcpReset: false + backendAddressPools: [ + { + id: resourceId('Microsoft.Network/loadBalancers/backendAddressPools', lbName, 'backend1') + } + ] + } + } + ] + inboundNatRules: [] + outboundRules: [] + } +} +``` + + + +## NOTES + +This rule only applies to probes for ports that commonly use HTTP or HTTPS protocols. + ## LINKS - [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy) - [Load Balancer health probes](https://learn.microsoft.com/azure/load-balancer/load-balancer-custom-probe-overview) - [Health Endpoint Monitoring pattern](https://learn.microsoft.com/azure/architecture/patterns/health-endpoint-monitoring) +- [Reliability in Load Balancer](https://learn.microsoft.com/azure/reliability/reliability-load-balancer) +- [Health Probes](https://learn.microsoft.com/azure/reliability/reliability-load-balancer#health-probes) - [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.network/loadbalancers) diff --git a/docs/en/rules/Azure.LB.StandardSKU.md b/docs/en/rules/Azure.LB.StandardSKU.md index b2b57ce3992..39c281139fd 100644 --- a/docs/en/rules/Azure.LB.StandardSKU.md +++ b/docs/en/rules/Azure.LB.StandardSKU.md @@ -36,41 +36,32 @@ For example: ```json { - "apiVersion": "2020-07-01", - "name": "[parameters('name')]", - "type": "Microsoft.Network/loadBalancers", - "location": "[parameters('location')]", - "dependsOn": [], - "tags": {}, - "properties": { - "frontendIPConfigurations": [ - { - "name": "frontend-ip-config", - "properties": { - "privateIPAddress": null, - "privateIPAddressVersion": "IPv4", - "privateIPAllocationMethod": "Dynamic", - "subnet": { - "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/lb-rg/providers/Microsoft.Network/virtualNetworks/lb-vnet/subnets/default" - } - }, - "zones": [ - "1", - "2", - "3" - ] - } - ], - "backendAddressPools": [], - "probes": [], - "loadBalancingRules": [], - "inboundNatRules": [], - "outboundRules": [] - }, - "sku": { - "name": "Standard", - "tier": "[parameters('tier')]" - } + "type": "Microsoft.Network/loadBalancers", + "apiVersion": "2023-09-01", + "name": "[parameters('lbName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard", + "tier": "Regional" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "frontendIPConfig", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[reference(resourceId('Microsoft.Network/virtualNetworks', parameters('name')), '2023-09-01').subnets[1].id]" + } + }, + "zones": [ + "1", + "2", + "3" + ] + } + ] + } } ``` @@ -83,11 +74,12 @@ To configure Standard SKU for a load balancer. For example: ```bicep -resource lb_001 'Microsoft.Network/loadBalancers@2021-02-01' = { +resource internal_lb 'Microsoft.Network/loadBalancers@2023-09-01' = { name: lbName location: location sku: { name: 'Standard' + tier: 'Regional' } properties: { frontendIPConfigurations: [ @@ -110,6 +102,8 @@ resource lb_001 'Microsoft.Network/loadBalancers@2021-02-01' = { } ``` + + ## LINKS - [RE:04 Target metrics](https://learn.microsoft.com/azure/well-architected/reliability/metrics) diff --git a/docs/examples-vnet.bicep b/docs/examples-vnet.bicep index 7577f173edd..c9f5051be4a 100644 --- a/docs/examples-vnet.bicep +++ b/docs/examples-vnet.bicep @@ -185,6 +185,80 @@ resource pip 'Microsoft.Network/publicIPAddresses@2023-09-01' = { ] } +// An example load balancer with serving HTTPS from a backend pool. +resource https_lb 'Microsoft.Network/loadBalancers@2023-09-01' = { + name: lbName + location: location + sku: { + name: 'Standard' + tier: 'Regional' + } + properties: { + frontendIPConfigurations: [ + { + name: 'frontend1' + properties: { + privateIPAddressVersion: 'IPv4' + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: subnet01.id + } + } + zones: [ + '2' + '3' + '1' + ] + } + ] + backendAddressPools: [ + { + name: 'backend1' + } + ] + probes: [ + { + name: 'https' + properties: { + protocol: 'HTTPS' + port: 443 + requestPath: '/health' + intervalInSeconds: 5 + numberOfProbes: 1 + } + } + ] + loadBalancingRules: [ + { + name: 'https' + properties: { + frontendIPConfiguration: { + id: resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', lbName, 'frontend1') + } + frontendPort: 443 + backendPort: 443 + enableFloatingIP: false + idleTimeoutInMinutes: 4 + protocol: 'TCP' + loadDistribution: 'Default' + probe: { + id: resourceId('Microsoft.Network/loadBalancers/probes', lbName, 'https') + } + disableOutboundSnat: true + enableTcpReset: false + backendAddressPools: [ + { + id: resourceId('Microsoft.Network/loadBalancers/backendAddressPools', lbName, 'backend1') + } + ] + } + } + ] + inboundNatRules: [] + outboundRules: [] + } +} + // An example public load balancer. resource public_lb 'Microsoft.Network/loadBalancers@2023-09-01' = { name: lbName diff --git a/docs/examples-vnet.json b/docs/examples-vnet.json index 090ba40b497..7678272d523 100644 --- a/docs/examples-vnet.json +++ b/docs/examples-vnet.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.26.54.24096", - "templateHash": "10466611904245566781" + "templateHash": "14583622702129964730" } }, "parameters": { @@ -208,6 +208,83 @@ "3" ] }, + { + "type": "Microsoft.Network/loadBalancers", + "apiVersion": "2023-09-01", + "name": "[parameters('lbName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard", + "tier": "Regional" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "frontend1", + "properties": { + "privateIPAddressVersion": "IPv4", + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), 'GatewaySubnet')]" + } + }, + "zones": [ + "2", + "3", + "1" + ] + } + ], + "backendAddressPools": [ + { + "name": "backend1" + } + ], + "probes": [ + { + "name": "https", + "properties": { + "protocol": "HTTPS", + "port": 443, + "requestPath": "/health", + "intervalInSeconds": 5, + "numberOfProbes": 1 + } + } + ], + "loadBalancingRules": [ + { + "name": "https", + "properties": { + "frontendIPConfiguration": { + "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', parameters('lbName'), 'frontend1')]" + }, + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 4, + "protocol": "TCP", + "loadDistribution": "Default", + "probe": { + "id": "[resourceId('Microsoft.Network/loadBalancers/probes', parameters('lbName'), 'https')]" + }, + "disableOutboundSnat": true, + "enableTcpReset": false, + "backendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', parameters('lbName'), 'backend1')]" + } + ] + } + } + ], + "inboundNatRules": [], + "outboundRules": [] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('name'), 'GatewaySubnet')]" + ] + }, { "type": "Microsoft.Network/loadBalancers", "apiVersion": "2023-09-01",