зеркало из
1
0
Форкнуть 0

feat(new): Added Azure.ASE.AvailabilityZone (#2985)

* feat(new): Added Azure.ASE.AvailabilityZone

* fix: Changelog

* fix: Changelog

* Update change log

* Update src/PSRule.Rules.Azure/en/PSRule-rules.psd1

Co-authored-by: Bernie White <bewhite@microsoft.com>

* Update src/PSRule.Rules.Azure/rules/Azure.ASE.Rule.ps1

Co-authored-by: Bernie White <bewhite@microsoft.com>

* fix: Fixed test

---------

Co-authored-by: Bernie White <bewhite@microsoft.com>
This commit is contained in:
Benjamin Engeset 2024-07-13 14:06:57 +02:00 коммит произвёл GitHub
Родитель b8078d7e7c
Коммит 28aa13cabf
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
6 изменённых файлов: 209 добавлений и 9 удалений

Просмотреть файл

@ -29,16 +29,21 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers
## Unreleased
What's changed since v1.38.0:
- New rules:
- App Service:
- Verify that app service plans have availability zones configured by @BenjaminEngeset.
[#2964](https://github.com/Azure/PSRule.Rules.Azure/issues/2964)
- App Service Environment:
- Verify that app service environments have availability zones configured by @BenjaminEngeset.
[#2964](https://github.com/Azure/PSRule.Rules.Azure/issues/2964)
- Azure SQL Database:
- Verify that Azure SQL databases have a customer-controlled maintenance window configured by @BenjaminEngeset.
[#2956](https://github.com/Azure/PSRule.Rules.Azure/issues/2956)
- Azure SQL Managed Instance:
- Verify that Azure SQL Managed Instances have a customer-controlled maintenance window configured by @BenjaminEngeset.
[#2979](https://github.com/Azure/PSRule.Rules.Azure/issues/2979)
- App Service:
- Verify that app service plans have availability zones configured by @BenjaminEngeset.
[#2964](https://github.com/Azure/PSRule.Rules.Azure/issues/2964)
## v1.38.0

Просмотреть файл

@ -0,0 +1,93 @@
---
severity: Important
pillar: Reliability
category: RE:05 Regions and availability zones
resource: App Service Environment
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ASE.AvailabilityZone/
---
# Deploy app service environments using availability zones
## SYNOPSIS
Deploy app service environments using availability zones in supported regions to ensure high availability and resilience.
## DESCRIPTION
App Service Environments support zone redundancy, which distributes your application running within the environment across Availablity Zones.
Each Availability Zone is a group of phyiscally separated data centers.
Deploying your application with zone redundancy:
- Scales your plan within the environment to a minimum of 3 instances in a highly available configuration.
Additional instances can be added manually or on-demand by using autoscale.
- Improves the resiliency against service disruptions or issues affecting a single zone.
Additionally:
- **Even Distribution**: If the instance count is larger than 3 and divisible by 3, instances are evenly distributed across the three zones.
- **Partial Distribution**: Instance counts beyond 3*N are spread across the remaining one or two zones to ensure balanced distribution.
**Important** Configuring zone redundancy with per-application scaling is possible but may increase costs and administrative overhead.
When `perSiteScaling` is enabled, each application can have its own scaling rules and run on dedicated instances.
To maintain zone redundancy, it is crucial that each applications scaling rules ensure a minimum of 3 instances.
Without explicitly configuring this minimum, the application may not meet the zone redundancy requirement.
## RECOMMENDATION
Consider using enabling zone redundancy using availability zones to improve the resiliency of your solution.
## EXAMPLES
### Configure with Azure template
To configure a zone-redundant app service environment:
- Set the `properties.zoneRedundant` property to `true`.
For example:
```json
{
"type": "Microsoft.Web/hostingEnvironments",
"apiVersion": "2022-09-01",
"name": "[parameters('name')]",
"location": "[parameters('location')]",
"kind": "ASEV3",
"properties": {
"zoneRedundant": true
}
}
```
### Configure with Bicep
To configure a zone-redundant app service environment:
- Set the `properties.zoneRedundant` property to `true`.
For example:
```bicep
resource ase 'Microsoft.Web/hostingEnvironments@2022-09-01' = {
name: name
location: location
kind 'ASEV3'
properties: {
zoneRedundant: true
}
}
```
## NOTES
Zone-redundancy is only supported for the `ASEV3` version.
Zone-redundancy is not supported for environments deployed on a dedicated host group.
## LINKS
- [RE:05 Regions and availability zones](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones)
- [Reliability in Azure App Service](https://learn.microsoft.com/azure/reliability/reliability-app-service)
- [Availability zone support](https://learn.microsoft.com/azure/reliability/reliability-app-service#availability-zone-support)
- [About App Service Environment](https://learn.microsoft.com/azure/app-service/environment/overview)
- [Azure resource deployment](https://learn.microsoft.com/azure/templates/microsoft.web/hostingenvironments)

Просмотреть файл

@ -112,6 +112,7 @@
InsecureParameterType = "The parameter '{0}' with type '{1}' is not secure."
AzureSQLMIMaintenanceWindow = "The managed instance ({0}) should have a customer-controlled maintenance window configured."
AzureSQLDatabaseMaintenanceWindow = "The {0} ({1}) should have a customer-controlled maintenance window configured."
ASEAvailabilityZoneVersion = "The app service environment ({0}) is not deployed with a version that supports zone-redundancy."
AppServiceAvailabilityZoneSKU = "The app service plan ({0}) is not deployed with a SKU that supports zone-redundancy."
AppServiceAvailabilityZone = "The app service plan ({0}) deployed to region ({1}) should use three availability zones from the following [{2}]."
}

Просмотреть файл

@ -5,7 +5,36 @@
# Validation rules for Azure App Service Environment
#
#region Rules
# Synopsis: Use ASEv3 as replacement for the classic app service environment versions ASEv1 and ASEv2.
Rule 'Azure.ASE.MigrateV3' -Ref 'AZR-000319' -Type 'Microsoft.Web/hostingEnvironments' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } {
$Assert.HasFieldValue($TargetObject, 'kind', 'ASEV3').Reason($LocalizedData.ClassicASEDeprecated, $PSRule.TargetName, $TargetObject.kind)
}
# Synopsis: Deploy app service environments using availability zones in supported regions to ensure high availability and resilience.
Rule 'Azure.ASE.AvailabilityZone' -Ref 'AZR-000443' -Type 'Microsoft.Web/hostingEnvironments' -Tag @{ release = 'GA'; ruleSet = '2024_09 '; 'Azure.WAF/pillar' = 'Reliability'; } {
# Dedicated host group does not support zone-redundancy.
if ($TargetObject.properties.dedicatedHostCount) {
return $Assert.Pass()
}
# Check if the region supports availability zones.
$provider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Web', 'hostingEnvironments')
$availabilityZones = GetAvailabilityZone -Location $TargetObject.Location -Zone $provider.ZoneMappings
# Don't flag if the region does not support availability zones.
if (-not $availabilityZones) {
return $Assert.Pass()
}
# Availability zones are only supported for the ASEv3 version (modern footprint).
$Assert.HasFieldValue($TargetObject, 'kind', 'ASEV3').Reason(
$LocalizedData.ASEAvailabilityZoneVersion,
$TargetObject.name
)
$Assert.HasFieldValue($TargetObject, 'properties.zoneRedundant', $true)
}
#endregion Rules

Просмотреть файл

@ -51,8 +51,32 @@ Describe 'Azure.ASE' -Tag 'ASE' {
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -BeIn 'environment-C';
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -BeIn 'environment-C', 'environment-E', 'environment-F';
}
It 'Azure.ASE.AvailabilityZone' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ASE.AvailabilityZone' };
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -BeIn 'environment-A', 'environment-B', 'environment-D';
$ruleResult[0].Reason | Should -BeExactly @(
"The app service environment (environment-A) is not deployed with a version that supports zone-redundancy."
"Path properties.zoneRedundant: Does not exist."
):
$ruleResult[1].Reason | Should -BeExactly @(
"The app service environment (environment-B) is not deployed with a version that supports zone-redundancy."
"Path properties.zoneRedundant: Is set to 'False'."
):
$ruleResult[2].Reason | Should -BeExactly "The app service environment (environment-D) is not deployed with a version that supports zone-redundancy.";
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -Be 'environment-C', 'environment-E', 'environment-F';
}
}
}

Просмотреть файл

@ -13,8 +13,7 @@
"virtualNetwork": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-A",
"subnet": "subnet-A"
},
"zoneRedundant": true
}
},
"ResourceGroupName": "rg-test",
"Type": "microsoft.web/hostingenvironments",
@ -52,7 +51,7 @@
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Web/hostingEnvironments/environment-B/serverfarms/plan-A",
"Identity": null,
"Kind": null,
"Location": "region",
"Location": "westeurope",
"ManagedBy": null,
"ResourceName": "plan-A",
"Name": "plan-A",
@ -88,7 +87,7 @@
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Web/hostingEnvironments/environment-C",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Web/hostingEnvironments/environment-C",
"Identity": null,
"Location": "westeurope",
"Location": "notregion",
"ManagedBy": null,
"ResourceName": "environment-C",
"Name": "environment-C",
@ -167,5 +166,54 @@
"Sku": null,
"Tags": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Web/hostingEnvironments/environment-E",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Web/hostingEnvironments/environment-E",
"Identity": null,
"Location": "westeurope",
"ManagedBy": null,
"ResourceName": "environment-E",
"Name": "environment-E",
"Kind": "ASEV3",
"Properties": {
"upgradePreference": "Early",
"virtualNetwork": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-A",
"subnet": "subnet-A"
},
"zoneRedundant": true
},
"ResourceGroupName": "rg-test",
"Type": "microsoft.web/hostingenvironments",
"ResourceType": "microsoft.web/hostingenvironments",
"Sku": null,
"Tags": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Web/hostingEnvironments/environment-F",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.Web/hostingEnvironments/environment-F",
"Identity": null,
"Location": "westeurope",
"ManagedBy": null,
"ResourceName": "environment-F",
"Name": "environment-E",
"Kind": "ASEV3",
"Properties": {
"upgradePreference": "Early",
"virtualNetwork": {
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-A",
"subnet": "subnet-A"
},
"dedicatedHostCount": 2,
"zoneRedundant": false
},
"ResourceGroupName": "rg-test",
"Type": "microsoft.web/hostingenvironments",
"ResourceType": "microsoft.web/hostingenvironments",
"Sku": null,
"Tags": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
}
]