Skip to content

Commit

Permalink
feat(new): Added Azure.PostgreSQL.MaintenanceWindow (Azure#2928)
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjaminEngeset authored Jun 11, 2024
1 parent 8ae0448 commit 3e5afed
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 5 deletions.
5 changes: 5 additions & 0 deletions docs/CHANGELOG-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers

## Unreleased

- New rules:
- Azure Database for PostgreSQL:
- Verify that Azure Database for PostgreSQL servers have a customer-controlled maintenance window configured by @BenjaminEngeset.
[#2927](https://github.com/Azure/PSRule.Rules.Azure/issues/2927)

What's changed since pre-release v1.37.0:

- New rules:
Expand Down
107 changes: 107 additions & 0 deletions docs/en/rules/Azure.PostgreSQL.MaintenanceWindow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
severity: Important
pillar: Reliability
category: RE:04 Target metrics
resource: Azure Database for PostgreSQL
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.PostgreSQL.MaintenanceWindow/
---

# Customer-controlled maintenance window configuration

## SYNOPSIS

Configure a customer-controlled maintenance window for Azure Database for PostgreSQL servers.

## DESCRIPTION

Azure Database for PostgreSQL flexible servers undergo periodic maintenance to ensure your managed database remains secure, stable, and up-to-date. This maintenance includes applying security updates, system upgrades, and software patches.

Maintenance windows can be scheduled in two ways for each flexible server:

- System-Managed Schedule: The system automatically selects a one-hour window between 11 PM and 7 AM in your server’s regional time.
- Custom Schedule: You can specify a preferred maintenance window by choosing the day of the week and a one-hour time window.

By configuring a customer-controlled maintenance window, you can schedule updates to occur during a preferred time, ideally outside business hours, minimizing disruptions.

Only the flexible server deployment model supports customer-controlled maintenance windows.

## RECOMMENDATION

Consider using a customer-controlled maintenance window to efficiently schedule updates and minimize disruptions.

## EXAMPLES

### Configure with Azure template

To configure servers that pass this rule:

- Set the `properties.maintenanceWindow.customWindow` property to `Enabled`.

For example:

```json
{
"type": "Microsoft.DBforPostgreSQL/flexibleServers",
"apiVersion": "2023-03-01-preview",
"name": "[parameters('serverName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_D16as",
"tier": "GeneralPurpose"
},
"properties": {
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]",
"createMode": "Default",
"version": "[parameters('postgresqlVersion')]",
"maintenanceWindow": {
"customWindow": "Enabled",
"dayOfWeek": "0",
"startHour": "1",
"startMinute": "0"
}
}
}
```

### Configure with Bicep

To configure servers that pass this rule:

- Set the `properties.maintenanceWindow.customWindow` property to `Enabled`.

For example:

```bicep
resource postgresqlDbServer 'Microsoft.DBforPostgreSQL/flexibleServers@2023-03-01-preview' = {
name: serverName
location: location
sku: {
name: 'Standard_D16as'
tier: 'GeneralPurpose'
}
properties: {
administratorLogin: administratorLogin
administratorLoginPassword: administratorLoginPassword
createMode: 'Default'
version: postgresqlVersion
maintenanceWindow: {
customWindow: 'Enabled'
dayOfWeek: 0
startHour: 1
startMinute: 0
}
}
}
```

## NOTES

The custom schedule maintenance window feature is only available for the flexible server deployment model.

## LINKS

- [RE:04 Target metrics](https://learn.microsoft.com/azure/well-architected/reliability/metrics)
- [Scheduled maintenance in Azure Database for PostgreSQL](https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-maintenance)
- [Select a maintenance window](https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-maintenance#select-a-maintenance-window)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.dbforpostgresql/flexibleservers)
18 changes: 18 additions & 0 deletions src/PSRule.Rules.Azure/rules/Azure.PostgreSQL.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,22 @@ spec:
- field: properties.authConfig.passwordAuth
equals: Disabled

---
# Synopsis: Configure a customer-controlled maintenance window for Azure Database for PostgreSQL servers.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Azure.PostgreSQL.MaintenanceWindow
ref: AZR-000433
tags:
release: GA
ruleSet: 2024_06
Azure.WAF/pillar: Reliability
spec:
type:
- Microsoft.DBforPostgreSQL/flexibleServers
condition:
field: properties.maintenanceWindow.customWindow
equals: Enabled

#endregion Region
28 changes: 23 additions & 5 deletions tests/PSRule.Rules.Azure.Tests/Azure.PostgreSQL.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ Describe 'Azure.PostgreSQL' -Tag 'PostgreSQL' {
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 4;
$ruleResult.TargetName | Should -BeIn 'server-A', 'server-B', 'server-E', 'server-F';
$ruleResult.Length | Should -Be 5;
$ruleResult.TargetName | Should -BeIn 'server-A', 'server-B', 'server-E', 'server-F', 'server-G';

$ruleResult[0].Reason | Should -BeExactly "The Azure Database for PostgreSQL 'server-B' should have geo-redundant backup configured.";
$ruleResult[1].Reason | Should -BeExactly "The Azure Database for PostgreSQL 'server-A' should have geo-redundant backup configured.";
Expand Down Expand Up @@ -168,8 +168,8 @@ Describe 'Azure.PostgreSQL' -Tag 'PostgreSQL' {
# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 6;
$ruleResult.TargetName | Should -BeIn 'server-A', 'server-B', 'server-D', 'server-E', 'ActiveDirectoryAdmin-A', 'ActiveDirectoryAdmin-C';
$ruleResult.Length | Should -Be 7;
$ruleResult.TargetName | Should -BeIn 'server-A', 'server-B', 'server-D', 'server-E', 'server-G', 'ActiveDirectoryAdmin-A', 'ActiveDirectoryAdmin-C';

$ruleResult[0].Reason | Should -BeIn 'Path properties.administratorType: Is null or empty.', 'Path properties.login: Is null or empty.', 'Path properties.sid: Is null or empty.';
$ruleResult[1].Reason | Should -BeIn "A sub-resource of type 'Microsoft.DBforPostgreSQL/servers/administrators' has not been specified.";
Expand All @@ -196,8 +196,26 @@ Describe 'Azure.PostgreSQL' -Tag 'PostgreSQL' {
# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult | Should -Not -BeNullOrEmpty;
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'server-F', 'server-G';
}

It 'Azure.PostgreSQL.MaintenanceWindow' {
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.PostgreSQL.MaintenanceWindow' };

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -BeIn 'server-D', 'server-E', 'server-F';

$ruleResult[0].Reason | Should -BeExactly "Path properties.maintenanceWindow.customWindow: The field 'properties.maintenanceWindow.customWindow' does not exist.";
$ruleResult[1].Reason | Should -BeExactly "Path properties.maintenanceWindow.customWindow: Is set to 'notset'.";
$ruleResult[2].Reason | Should -BeExactly "Path properties.maintenanceWindow.customWindow: Is set to 'Disabled'.";

# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -BeIn 'server-F';
$ruleResult.TargetName | Should -BeIn 'server-G';
}
}

Expand Down
54 changes: 54 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Resources.PostgreSQL.json
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,12 @@
"backup": {
"backupRetentionDays": 7
},
"maintenanceWindow": {
"customWindow": "notset",
"dayOfWeek": "notset",
"startHour": "notset",
"startMinute": "notset"
},
"highAvailability": {
"mode": "Disabled"
},
Expand Down Expand Up @@ -423,6 +429,12 @@
"backupRetentionDays": 7,
"geoRedundantBackup": "Disabled"
},
"maintenanceWindow": {
"customWindow": "Disabled",
"dayOfWeek": 0,
"startHour": 1,
"startMinute": 0
},
"highAvailability": {
"mode": "Disabled"
},
Expand Down Expand Up @@ -454,6 +466,48 @@
}
]
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DBforPostgreSQL/flexibleServers/server-G",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DBforPostgreSQL/flexibleServers/server-G",
"Location": "region",
"ResourceName": "server-G",
"Name": "server-G",
"Properties": {
"administratorLogin": "db-admin",
"authConfig": {
"activeDirectoryAuth": "Enabled",
"passwordAuth": "Disabled",
"tenantId": "00000000-0000-0000-0000-000000000000"
},
"storage": {
"storageSizeGB": 20
},
"backup": {
"backupRetentionDays": 7,
"geoRedundantBackup": "Disabled"
},
"maintenanceWindow": {
"customWindow": "Enabled",
"dayOfWeek": 0,
"startHour": 1,
"startMinute": 0
},
"highAvailability": {
"mode": "Disabled"
},
"version": "14",
"createMode": "Default"
},
"ResourceGroupName": "test-rg",
"Type": "Microsoft.DBforPostgreSQL/flexibleServers",
"ResourceType": "Microsoft.DBforPostgreSQL/flexibleServers",
"Sku": {
"Name": "E64",
"Tier": "MemoryOptimized"
},
"Tags": null,
"SubscriptionId": "00000000-0000-0000-0000-000000000000"
},
{
"Name": "ActiveDirectoryAdmin-A",
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DBforPostgreSQL/servers/server-B/administrators/ActiveDirectoryAdmin-A",
Expand Down

0 comments on commit 3e5afed

Please sign in to comment.