Skip to content

Commit

Permalink
Fixed Azure.AppGw.AvailabilityZone with zonal config #3061 (#3094)
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite authored Oct 11, 2024
1 parent 194b235 commit ddeb333
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 92 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ What's changed since pre-release v1.39.0:
- Bug fixes:
- Fixed `GetBicepParamResources` exception when expanding `Microsoft.Graph/groups` resource by @BernieWhite.
[#3062](https://github.com/Azure/PSRule.Rules.Azure/issues/3062)
- Fixed `Azure.AppGw.AvailabilityZone` passes when a zonal configuration is used by @BernieWhite.
[#3061](https://github.com/Azure/PSRule.Rules.Azure/issues/3061)

## v1.39.0

Expand Down
146 changes: 97 additions & 49 deletions docs/en/rules/Azure.AppGw.AvailabilityZone.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
reviewed: 2024-10-11
severity: Important
pillar: Reliability
category: RE:05 Regions and availability zones
Expand All @@ -10,109 +11,136 @@ online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AppGw.

## SYNOPSIS

Application gateways should use availability zones in supported regions for high availability.
Application Gateway (App Gateway) should use availability zones in supported regions for improved resiliency.

## DESCRIPTION

Application gateways using availability zones improve reliability and ensure availability during failure scenarios
affecting a data center within a region. A zone redundant Application gateway or Web Application Firewall (WAF)
deployment can spread across multiple availability zones, which ensures the application gateway will continue
running even if another zone has gone down. Backend pools for applications can be similarly distributed across
availability zones.
App Gateway V2 (Standard_v2 and WAF_v2) supports the use of availability zones to improve resiliency.
Each Availability Zone is a group of physically separated data centers.

## RECOMMENDATION

Consider using availability zones for Application gateways deployed with V2 SKU (Standard_v2, WAF_v2).
When configured, App Gateway spreads infrastructure instances across multiple availability zones you choose.
When a zone impacting event occurs, Application Gateway is able to continue processing network traffic from other zones.

## NOTES
Key points when configuring availability zones:

This rule applies when analyzing resources deployed to Azure using *pre-flight* and *in-flight* data.
- **Configure two (2) or more** — Configuring only a single zone (zonal) doesn't provide zone redundancy.
If the configured zone fails, the service fails.
Ideally, configure three zones. i.e. `1`, `2`, and `3`.
- **Consider the network path and connected services** — Look along the network path to other services, to match zones.
If App Gateway is deployed to zones `1` and `2` but your applications backend or firewall is deployed to zone `3`,
failure of any zone would cause failure of the application.
- **Available regions** — Availability zones are not available in all Azure regions/ locations.
To use availability zones, choose regions that support this feature for the Azure services in your application.
- **Supported SKUs** — Availability zones are not supported with the legacy V1 SKU.
You must use the `Standard_v2` or `WAF_v2` SKU to configure availability zones.

This rule fails when `"zones"` is `null`, `[]` or not set when the Application gateway is deployed with V2
SKU (Standard_v2, WAF_v2) and there are supported availability zones for the given region.
## RECOMMENDATION

Configure `AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST` to set additional availability zones that need to be
supported which are not in the existing [providers](https://github.com/Azure/PSRule.Rules.Azure/blob/main/data/providers/)
for namespace `Microsoft.Network` and resource type `applicationGateways`.

```yaml
# YAML: The default AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST configuration option
configuration:
AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST: []
```
Consider using the Application Gateway V2 SKU and configure at least two (2) availability zones to improve resiliency.

## EXAMPLES

### Configure with Azure template

To set availability zones for an Application gateway
To deploy Application Gateways that pass this rule:

- Set `zones` to any or all of `["1", "2", "3"]`.
- Set `properties.sku.name` and `properties.sku.tier` to `Standard_v2` or `WAF_v2`.

For example:

```json
{
"name": "appGw-001",
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2019-09-01",
"location": "[resourceGroup().location]",
"zones": [
"1",
"2",
"3"
],
"tags": {},
"properties": {
"sku": {
"name": "WAF_v2",
"tier": "WAF_v2"
},
"autoscaleConfiguration": {
"minCapacity": 2,
"maxCapacity": 3
}
{
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2024-01-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"zones": [
"1",
"2",
"3"
],
"properties": {
"sku": {
"name": "WAF_v2",
"tier": "WAF_v2"
},
"sslPolicy": {
"policyType": "Custom",
"minProtocolVersion": "TLSv1_2",
"cipherSuites": [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
},
"autoscaleConfiguration": {
"minCapacity": 2,
"maxCapacity": 3
},
"firewallPolicy": {
"id": "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', 'agwwaf')]"
}
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', 'agwwaf')]"
]
}
```

### Configure with Bicep

To set availability zones for an Application gateway
To deploy Application Gateways that pass this rule:

- Set `zones` to any or all of `["1", "2", "3"]`.
- Set `zones` to any or all of `['1', '2', '3']`.
- Set `properties.sku.name` and `properties.sku.tier` to `Standard_v2` or `WAF_v2`.

For example:

```bicep
resource name_resource 'Microsoft.Network/applicationGateways@2019-09-01' = {
name: 'appGw-001'
resource appgw 'Microsoft.Network/applicationGateways@2024-01-01' = {
name: name
location: location
zones: [
'1'
'2'
'3'
]
tags: {}
properties: {
sku: {
name: 'WAF_v2'
tier: 'WAF_v2'
}
sslPolicy: {
policyType: 'Custom'
minProtocolVersion: 'TLSv1_2'
cipherSuites: [
'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384'
'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256'
'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'
'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
]
}
autoscaleConfiguration: {
minCapacity: 2
maxCapacity: 3
}
firewallPolicy: {
id: waf.id
}
}
}
```

<!-- external:avm avm/res/network/application-gateway zones,sku -->

### Configure with Azure CLI

#### Create WAFv2 Application Gateway in Zone 1, 2 and 3

To deploy Application Gateways that pass this rule:

```bash
az network application-gateway create \
--name '<application_gateway_name>' \
Expand All @@ -127,8 +155,28 @@ az network application-gateway create \
--servers '<address_1>' '<address_2>'
```

## NOTES

This rule fails when `"zones"` is `null`, `[]` or not set when the Application gateway is deployed with V2
SKU (Standard_v2, WAF_v2) and there are supported availability zones for the given region.

### Rule configuration

<!-- module:config rule AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST -->

Configure `AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST` to set additional availability zones that need to be
supported which are not in the existing [providers](https://github.com/Azure/PSRule.Rules.Azure/tree/main/data/providers/)
for namespace `Microsoft.Network` and resource type `applicationGateways`.

```yaml
# YAML: The default AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST configuration option
configuration:
AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST: []
```
## LINKS
- [RE:05 Regions and availability zones](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones)
- [What are availability zones?](https://learn.microsoft.com/azure/reliability/availability-zones-overview)
- [Autoscaling and Zone-redundant Application Gateway v2](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.network/applicationgateways)
24 changes: 6 additions & 18 deletions docs/examples/resources/appgw.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ param name string
@description('The location resources will be deployed.')
param location string = resourceGroup().location

resource app_gw 'Microsoft.Network/applicationGateways@2023-09-01' = {
// An example of an Application Gateway with a WAF_v2 SKU.
resource appgw 'Microsoft.Network/applicationGateways@2024-01-01' = {
name: name
location: location
zones: [
'1'
'2'
'3'
]
tags: {}
properties: {
sku: {
name: 'WAF_v2'
Expand All @@ -31,30 +31,18 @@ resource app_gw 'Microsoft.Network/applicationGateways@2023-09-01' = {
'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256'
]
}
gatewayIPConfigurations: []
frontendIPConfigurations: []
frontendPorts: []
backendAddressPools: []
backendHttpSettingsCollection: []
httpListeners: []
requestRoutingRules: []
enableHttp2: false
sslCertificates: []
probes: []
autoscaleConfiguration: {
minCapacity: 2
maxCapacity: 3
}
webApplicationFirewallConfiguration: {
enabled: true
firewallMode: 'Detection'
ruleSetType: 'OWASP'
ruleSetVersion: '3.0'
firewallPolicy: {
id: waf.id
}
}
}

resource waf 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2023-09-01' = {
// An example of an Web Application Firewall policy configure with OWASP and Microsoft_BotManagerRuleSet rule sets.
resource waf 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-01-01' = {
name: 'agwwaf'
location: location
properties: {
Expand Down
31 changes: 10 additions & 21 deletions docs/examples/resources/appgw.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.25.53.49325",
"templateHash": "16003563993180625268"
"version": "0.30.23.60470",
"templateHash": "4359475365574020257"
}
},
"parameters": {
Expand All @@ -26,15 +26,14 @@
"resources": [
{
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2023-09-01",
"apiVersion": "2024-01-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"zones": [
"1",
"2",
"3"
],
"tags": {},
"properties": {
"sku": {
"name": "WAF_v2",
Expand All @@ -50,31 +49,21 @@
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
]
},
"gatewayIPConfigurations": [],
"frontendIPConfigurations": [],
"frontendPorts": [],
"backendAddressPools": [],
"backendHttpSettingsCollection": [],
"httpListeners": [],
"requestRoutingRules": [],
"enableHttp2": false,
"sslCertificates": [],
"probes": [],
"autoscaleConfiguration": {
"minCapacity": 2,
"maxCapacity": 3
},
"webApplicationFirewallConfiguration": {
"enabled": true,
"firewallMode": "Detection",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
"firewallPolicy": {
"id": "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', 'agwwaf')]"
}
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', 'agwwaf')]"
]
},
{
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies",
"apiVersion": "2023-09-01",
"apiVersion": "2024-01-01",
"name": "agwwaf",
"location": "[parameters('location')]",
"properties": {
Expand Down
Loading

0 comments on commit ddeb333

Please sign in to comment.