Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Application Gateway Availability Zone Rule #942

Merged
merged 7 commits into from Sep 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Expand Up @@ -30,6 +30,7 @@
"NSGs",
"OWASP",
"Qualys",
"APPGW",
"RBAC",
"SIEM",
"SKUs",
Expand Down
3 changes: 2 additions & 1 deletion docs/en/baselines/Azure.All.md
Expand Up @@ -4,7 +4,7 @@ Includes all Azure rules.

## Rules

The following rules are included within `Azure.All`. This baseline includes a total of 225 rules.
The following rules are included within `Azure.All`. This baseline includes a total of 226 rules.

Name | Synopsis | Severity
---- | -------- | --------
Expand Down Expand Up @@ -56,6 +56,7 @@ Name | Synopsis | Severity
[Azure.APIM.SampleProducts](../rules/Azure.APIM.SampleProducts.md) | Remove starter and unlimited sample products. | Awareness
[Azure.AppConfig.Name](../rules/Azure.AppConfig.Name.md) | App Configuration store names should meet naming requirements. | Awareness
[Azure.AppConfig.SKU](../rules/Azure.AppConfig.SKU.md) | App Configuration should use a minimum size of Standard. | Important
[Azure.AppGw.AvailabilityZone](../rules/Azure.AppGw.AvailabilityZone.md) | Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability. | Important
[Azure.AppGw.MinInstance](../rules/Azure.AppGw.MinInstance.md) | Application Gateways should use a minimum of two instances. | Important
[Azure.AppGw.MinSku](../rules/Azure.AppGw.MinSku.md) | Application Gateway should use a minimum instance size of Medium. | Important
[Azure.AppGw.OWASP](../rules/Azure.AppGw.OWASP.md) | Application Gateway Web Application Firewall (WAF) should use OWASP 3.x rules. | Important
Expand Down
3 changes: 2 additions & 1 deletion docs/en/baselines/Azure.Default.md
Expand Up @@ -4,7 +4,7 @@ Default baseline for Azure rules.

## Rules

The following rules are included within `Azure.Default`. This baseline includes a total of 221 rules.
The following rules are included within `Azure.Default`. This baseline includes a total of 222 rules.

Name | Synopsis | Severity
---- | -------- | --------
Expand Down Expand Up @@ -52,6 +52,7 @@ Name | Synopsis | Severity
[Azure.APIM.SampleProducts](../rules/Azure.APIM.SampleProducts.md) | Remove starter and unlimited sample products. | Awareness
[Azure.AppConfig.Name](../rules/Azure.AppConfig.Name.md) | App Configuration store names should meet naming requirements. | Awareness
[Azure.AppConfig.SKU](../rules/Azure.AppConfig.SKU.md) | App Configuration should use a minimum size of Standard. | Important
[Azure.AppGw.AvailabilityZone](../rules/Azure.AppGw.AvailabilityZone.md) | Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability. | Important
[Azure.AppGw.MinInstance](../rules/Azure.AppGw.MinInstance.md) | Application Gateways should use a minimum of two instances. | Important
[Azure.AppGw.MinSku](../rules/Azure.AppGw.MinSku.md) | Application Gateway should use a minimum instance size of Medium. | Important
[Azure.AppGw.OWASP](../rules/Azure.AppGw.OWASP.md) | Application Gateway Web Application Firewall (WAF) should use OWASP 3.x rules. | Important
Expand Down
3 changes: 2 additions & 1 deletion docs/en/baselines/Azure.Preview.md
Expand Up @@ -4,7 +4,7 @@ Includes Azure features in preview.

## Rules

The following rules are included within `Azure.Preview`. This baseline includes a total of 225 rules.
The following rules are included within `Azure.Preview`. This baseline includes a total of 226 rules.

Name | Synopsis | Severity
---- | -------- | --------
Expand Down Expand Up @@ -56,6 +56,7 @@ Name | Synopsis | Severity
[Azure.APIM.SampleProducts](../rules/Azure.APIM.SampleProducts.md) | Remove starter and unlimited sample products. | Awareness
[Azure.AppConfig.Name](../rules/Azure.AppConfig.Name.md) | App Configuration store names should meet naming requirements. | Awareness
[Azure.AppConfig.SKU](../rules/Azure.AppConfig.SKU.md) | App Configuration should use a minimum size of Standard. | Important
[Azure.AppGw.AvailabilityZone](../rules/Azure.AppGw.AvailabilityZone.md) | Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability. | Important
[Azure.AppGw.MinInstance](../rules/Azure.AppGw.MinInstance.md) | Application Gateways should use a minimum of two instances. | Important
[Azure.AppGw.MinSku](../rules/Azure.AppGw.MinSku.md) | Application Gateway should use a minimum instance size of Medium. | Important
[Azure.AppGw.OWASP](../rules/Azure.AppGw.OWASP.md) | Application Gateway Web Application Firewall (WAF) should use OWASP 3.x rules. | Important
Expand Down
188 changes: 188 additions & 0 deletions docs/en/rules/Azure.AppGw.AvailabilityZone.md
@@ -0,0 +1,188 @@
---
severity: Important
pillar: Reliability
category: Design
resource: Application Gateway
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.AppGw.AvailabilityZone/
---

# Application gateways should use Availability zones in supported regions

## SYNOPSIS

Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability.

## 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 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.

## RECOMMENDATION

Consider using availability zones for Application gateways deployed with V2 SKU(Standard_v2, WAF_v2).

## NOTES

This rule applies when analyzing resources deployed to Azure using *pre-flight* and *in-flight* data.

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.

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.json) 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: []
```

## EXAMPLES

### Configure with Azure template

To set availability zones for an Application gateway

- 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": "[parameters('applicationGatewayName')]",
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2019-09-01",
"location": "[parameters('location')]",
"zones": [
"1",
"2",
"3"
],
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIpAddressName'))]"
],
"tags": {},
"properties": {
"sku": {
"name": "WAF_v2",
"tier": "WAF_v2"
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGwPublicFrontendIp",
"properties": {
"PublicIPAddress": {
"id": "[variables('publicIPRef')]"
}
}
}
],
"frontendPorts": [
{
"name": "port_80",
"properties": {
"Port": 80
}
}
],
"backendAddressPools": [
{
"name": "bepool",
"properties": {
"backendAddresses": []
}
}
],
"backendHttpSettingsCollection": [
{
"name": "http_settings",
"properties": {
"Port": 80,
"Protocol": "Http",
"cookieBasedAffinity": "Disabled",
"requestTimeout": 20
}
}
],
"httpListeners": [
{
"name": "http-listener",
"properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('applicationGatewayId'), '/frontendIPConfigurations/appGwPublicFrontendIp')]"
},
"frontendPort": {
"id": "[concat(variables('applicationGatewayId'), '/frontendPorts/port_80')]"
},
"protocol": "Http",
"sslCertificate": null
}
}
],
"requestRoutingRules": [
{
"Name": "http-rule",
"properties": {
"RuleType": "Basic",
"httpListener": {
"id": "[concat(variables('applicationGatewayId'), '/httpListeners/http-listener')]"
},
"priority": null,
"backendAddressPool": {
"id": "[concat(variables('applicationGatewayId'), '/backendAddressPools/bepool')]"
},
"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayId'), '/backendHttpSettingsCollection/http_settings')]"
}
}
}
],
"enableHttp2": false,
"sslCertificates": [],
"probes": [],
"autoscaleConfiguration": {
"minCapacity": "[parameters('capacity')]",
"maxCapacity": "[parameters('autoScaleMaxCapacity')]"
},
"webApplicationFirewallConfiguration": {
"enabled": true,
"firewallMode": "Detection",
"ruleSetType": "OWASP",
"ruleSetVersion": "3.0"
}
}
}
```

### Configure with Azure CLI

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

```bash
az network application-gateway create \
--name '<application_gateway_name>' \
--location '<location>' \
--resource-group '<resource_group>' \
--capacity '<capacity>' \
--sku WAF_v2 \
--public-ip-address '<public_ip_address>' \
--vnet-name '<virtual_network_name>' \
--subnet '<subnet_name>' \
--zones 1 2 3 \
--servers '<address_1>' '<address_2>'
```

## LINKS

- [Azure template reference](https://docs.microsoft.com/azure/templates/microsoft.network/applicationgateways?tabs=json)
- [Autoscaling and Zone-redundant Application Gateway v2](https://docs.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant)
- [Use zone-aware services](https://docs.microsoft.com/azure/architecture/framework/resiliency/design-best-practices#use-zone-aware-services)
1 change: 1 addition & 0 deletions docs/en/rules/module.md
Expand Up @@ -217,6 +217,7 @@ Name | Synopsis | Severity
[Azure.AKS.AvailabilityZone](Azure.AKS.AvailabilityZone.md) | AKS clusters deployed with virtual machine scale sets should use availability zones in supported regions for high availability. | Important
[Azure.AKS.PoolVersion](Azure.AKS.PoolVersion.md) | AKS node pools should match Kubernetes control plane version. | Important
[Azure.AKS.Version](Azure.AKS.Version.md) | AKS control plane and nodes pools should use a current stable release. | Important
[Azure.AppGw.AvailabilityZone](Azure.AppGw.AvailabilityZone.md) | Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability. | Important

### Load balancing and failover

Expand Down
1 change: 1 addition & 0 deletions docs/en/rules/resource.md
Expand Up @@ -74,6 +74,7 @@ Name | Synopsis | Severity

Name | Synopsis | Severity
---- | -------- | --------
[Azure.AppGw.AvailabilityZone](Azure.AppGw.AvailabilityZone.md) | Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability. | Important
[Azure.AppGw.MinInstance](Azure.AppGw.MinInstance.md) | Application Gateways should use a minimum of two instances. | Important
[Azure.AppGw.MinSku](Azure.AppGw.MinSku.md) | Application Gateway should use a minimum instance size of Medium. | Important
[Azure.AppGw.OWASP](Azure.AppGw.OWASP.md) | Application Gateway Web Application Firewall (WAF) should use OWASP 3.x rules. | Important
Expand Down
15 changes: 12 additions & 3 deletions docs/setup/configuring-rules.md
Expand Up @@ -191,9 +191,17 @@ configuration:
AZURE_AKS_CNI_MINIMUM_CLUSTER_SUBNET_SIZE: 26
```

### Azure AKS additional region availability zone list
### Additional region availability zone list

This configuration option adds availability zones that are not included in the existing [providers](https://github.com/Azure/PSRule.Rules.Azure/blob/main/data/providers.json) for namespace `Microsoft.Compute` and resource type `virtualMachineScaleSets`.
This configuration option adds availability zones that are not included in the existing [providers](https://github.com/Azure/PSRule.Rules.Azure/blob/main/data/providers.json).

The following providers are supported:
- `Microsoft.Compute/virtualMachineScaleSets`
- `Microsoft.Network/applicationGateways`

The following rules and configuration options are supported:
- `Azure.AKS.AvailabilityZone` - `AZURE_AKS_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST`
- `Azure.AppGw.AvailabilityZone` - `AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST`

Syntax:

Expand Down Expand Up @@ -233,11 +241,12 @@ The above example, both these forms of location are accepted:
* `Australia Southeast` or `australiasoutheast`
* `Norway East` or `norwayeast`

The `Azure.AKS.AvailabilityZone` rule normalizes these location formats so either is accepted in the configuration.
The rules normalize these location formats so either is accepted in the configuration.

!!! Note
The above locations in the example do **not** currently support availability zones.
If they do in the future, you can configure this option to add them prior to PSRule for Azure support.
The above shows examples specific to `Azure.AKS.AvailabilityZone`, but behavior is consistent across all supported rules.

### Azure AKS enabled platform log categories list

Expand Down
1 change: 1 addition & 0 deletions src/PSRule.Rules.Azure/en/PSRule-rules.psd1
Expand Up @@ -47,4 +47,5 @@
ExpressionInTemplate = "The expression '{0}' was found in the template."
SubResourceNotFound = "A sub-resource of type '{0}' has not been specified."
ParameterValueNotSet = "The parameter '{0}' must have a value or Key Vault reference set."
AppGWAvailabilityZone = "The application gateway ({0}) deployed to region ({1}) should use following availability zones [{2}]."
}
37 changes: 37 additions & 0 deletions src/PSRule.Rules.Azure/rules/Azure.AppGw.Rule.ps1
Expand Up @@ -76,6 +76,43 @@ Rule 'Azure.AppGw.UseHTTPS' -Type 'Microsoft.Network/applicationGateways' -Tag @
}
}

# Synopsis: Application gateways deployed with V2 SKU(Standard_v2, WAF_v2) should use availability zones in supported regions for high availability.
Rule 'Azure.AppGw.AvailabilityZone' -Type 'Microsoft.Network/applicationGateways' -Tag @{ release = 'GA'; ruleSet = '2021_09'; } {

# Availability zones only available in v2 tiers of Application Gateway
$isV2Sku = $Assert.In($TargetObject, 'Properties.sku.tier', @('Standard_v2', 'WAF_v2')).Result;

if (-not $isV2Sku -or [string]::IsNullOrEmpty($TargetObject.Location)) {
return $Assert.Pass();
}

$configurationZones = $Configuration.AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST;

$appGatewayProvider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Network', 'applicationGateways');

if ($configurationZones.Length -gt 0) {

# Merge configuration options and default zone mappings together
# We put configuration options at the beginning so they are processed first
$availabilityZones = @($configurationZones) + @($appGatewayProvider.ZoneMappings);
}
else {
$availabilityZones = $appGatewayProvider.ZoneMappings;
}

$location = GetNormalLocation -Location $TargetObject.Location;

$locationAvailabilityZones = $availabilityZones | Where-Object { (GetNormalLocation -Location $_.Location) -eq $location } | Select-Object -ExpandProperty Zones -First 1;

if (-not $locationAvailabilityZones) {
return $Assert.Pass();
}

$Assert.HasFieldValue($TargetObject, 'zones').
Reason($LocalizedData.AppGWAvailabilityZone, $TargetObject.name, $location, ($locationAvailabilityZones -join ', '));

} -Configure @{ AZURE_APPGW_ADDITIONAL_REGION_AVAILABILITY_ZONE_LIST = @() }

#endregion Application Gateway

#region Helper functions
Expand Down