Skip to content

Commit

Permalink
feat(new): Added Azure.ServiceBus.GeoReplica (Azure#2989)
Browse files Browse the repository at this point in the history
* feat(new): Added Azure.ServiceBus.GeoReplica

* feat: Updated Azure.ServiceBus.GeoReplica

* Update docs/en/rules/Azure.ServiceBus.GeoReplica.md

Co-authored-by: Bernie White <[email protected]>

* Update docs/en/rules/Azure.ServiceBus.GeoReplica.md

Co-authored-by: Bernie White <[email protected]>

* Update docs/en/rules/Azure.ServiceBus.GeoReplica.md

Co-authored-by: Bernie White <[email protected]>

---------

Co-authored-by: Bernie White <[email protected]>
  • Loading branch information
BenjaminEngeset and BernieWhite authored Jul 16, 2024
1 parent 1c8de18 commit 9dfb8c5
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 8 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:
- Service Bus:
- Verify that service bus namespaces have geo-replication configured by @BenjaminEngeset.
[#2988](https://github.com/Azure/PSRule.Rules.Azure/issues/2988)

What's changed since v1.38.0:

- New rules:
Expand Down
131 changes: 131 additions & 0 deletions docs/en/rules/Azure.ServiceBus.GeoReplica.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
severity: Important
pillar: Reliability
category: RE:05 Redundancy
resource: Service Bus
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.ServiceBus.GeoReplica/
---

# Geo-replication

## SYNOPSIS

Enhance resilience to regional outages by replicating namespaces.

## DESCRIPTION

By default, an service bus namespace and its data and metadata is in a single region.

The geo-replication feature ensures that the metadata and data of a namespace are continuously replicated from a primary region to one or more secondary regions.

The following will be replicated:

- Queues, topics, subscriptions, filters.
- Data, which resides in the entities.
- All state changes and property changes executed against the messages within a namespace.
- Namespace configuration.

Replicating your namespace adds the following benefits:

- Added resiliency for localized outages contained to a region.
- Regional compartmentalization.

This feature allows promoting any secondary region to primary, reassigning the namespace name and switching roles between regions. Promotion is nearly instantaneous.

There are currently several limitations to the feature. For more details, refer to the documentation.

## RECOMMENDATION

Consider replicating service bus namespaces to improve resiliency to region outages.

## EXAMPLES

### Configure with Azure template

To deploy namespaces that pass this rule:

- Set the `sku.name` property to `Premium`. This only applies to new namespaces.
- For existing namespaces first, migrate to a namespace deployed with a premium SKU.
- Configure the `properties.geoDataReplication.locations` array with two or more supported region elements.

For example:

```json
{
"type": "Microsoft.ServiceBus/namespaces",
"apiVersion": "2023-01-01-preview",
"name": "[parameters('serviceBusName')]",
"location": "[parameters('primaryLocation')]",
"sku": {
"name": "Premium",
"tier": "Premium",
"capacity": 1
},
"properties": {
"geoDataReplication": {
"maxReplicationLagDurationInSeconds": "[parameters('maxReplicationLagInSeconds')]",
"locations": [
{
"locationName": "[parameters('primaryLocation')]",
"roleType": "Primary"
},
{
"locationName": "[parameters('secondaryLocation')]",
"roleType": "Secondary"
}
]
}
}
}
```

### Configure with Bicep

To deploy namespaces that pass this rule:

- Set the `sku.name` property to `Premium`. This only applies to new namespaces.
- For existing namespaces first, migrate to a namespace deployed with a premium SKU.
- Configure the `properties.geoDataReplication.locations` array with two or more supported region elements.

For example:

```bicep
resource sb 'Microsoft.ServiceBus/namespaces@2023-01-01-preview' = {
name: serviceBusName
location: primaryLocation
sku: {
name: 'Premium'
tier: 'Premium'
capacity: 1
}
properties: {
geoDataReplication: {
maxReplicationLagDurationInSeconds: maxReplicationLagInSeconds
locations: [
{
locationName: primaryLocation
roleType: 'Primary'
}
{
locationName: secondaryLocation
roleType: 'Secondary'
}
]
}
}
}
```

## NOTES

This feature is only supported for the `Premium` SKU.

This feature is currently in preview.

## LINKS

- [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy)
- [Geo-replication](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-geo-replication)
- [Configure geo-replication](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-geo-replication#setup)
- [Migrate existing Azure Service Bus standard namespaces to the premium tier](https://learn.microsoft.com/azure/service-bus-messaging/service-bus-migrate-standard-premium)
- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.servicebus/namespaces)
25 changes: 23 additions & 2 deletions src/PSRule.Rules.Azure/rules/Azure.ServiceBus.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,33 @@ metadata:
Azure.MCSB.v1/control: DP-3
spec:
type:
- Microsoft.ServiceBus/namespaces
- Microsoft.ServiceBus/namespaces
condition:
field: properties.minimumTlsVersion
equals: '1.2'

---
# Synopsis: Enhance resilience to regional outages by replicating namespaces.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Azure.ServiceBus.GeoReplica
ref: AZR-000444
tags:
release: preview
ruleSet: 2024_09
Azure.WAF/pillar: Reliability
spec:
type:
- Microsoft.ServiceBus/namespaces
condition:
allOf:
# Geo-replication is only available for the Premium SKU.
- field: sku.name
equals: Premium
- field: properties.geoDataReplication.locations
greaterOrEquals: 2

#endregion Rules

#region Selectors
Expand All @@ -67,5 +89,4 @@ spec:
- Microsoft.ServiceBus/namespaces
- field: sku.name
equals: Premium

#endregion Selectors
20 changes: 20 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Azure.ServiceBus.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,26 @@ Describe 'Azure.ServiceBus' -Tag 'ServiceBus' {
$ruleResult.Length | Should -Be 2;
$ruleResult.TargetName | Should -BeIn 'servicens-C', 'servicens-E';
}

It 'Azure.ServiceBus.GeoReplica' {
$dataPath = Join-Path -Path $here -ChildPath 'Resources.ServiceBus.json';
$result = Invoke-PSRule @invokeParams -InputPath $dataPath;
$filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.ServiceBus.GeoReplica' };

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -Be 'servicens-A', 'servicens-B', 'servicens-C';

$ruleResult[0].Reason | Should -BeExactly "Path sku.name: Is set to 'Standard'.";
$ruleResult[1].Reason | Should -BeExactly "Path properties.geoDataReplication.locations: The field 'properties.geoDataReplication.locations' does not exist.";
$ruleResult[2].Reason | Should -BeExactly "Path properties.geoDataReplication.locations: The value 'System.Object[]' is not >= 2.";

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

Context 'With Template' {
Expand Down
47 changes: 41 additions & 6 deletions tests/PSRule.Rules.Azure.Tests/Resources.ServiceBus.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.ServiceBus/namespaces/servicens-C",
"Identity": null,
"Kind": null,
"Location": "West Europe",
"Location": "centraluseuap",
"ManagedBy": null,
"ResourceName": "servicens-C",
"Name": "servicens-C",
Expand All @@ -223,7 +223,16 @@
"createdAt": "2022-06-30T13:23:58.58Z",
"updatedAt": "2022-08-04T10:21:56.053Z",
"serviceBusEndpoint": "https://servicens-C.servicebus.windows.net:443/",
"status": "Active"
"status": "Active",
"geoDataReplication": {
"maxReplicationLagDurationInSeconds": "300",
"locations": [
{
"locationName": "centraluseuap",
"roleType": "Primary"
}
]
}
},
"ResourceGroupName": "test-rg",
"Type": "Microsoft.ServiceBus/namespaces",
Expand Down Expand Up @@ -377,7 +386,7 @@
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.ServiceBus/namespaces/servicens-D",
"Identity": null,
"Kind": null,
"Location": "East US",
"Location": "centraluseuap",
"ManagedBy": null,
"ResourceName": "servicens-D",
"Name": "servicens-D",
Expand All @@ -392,7 +401,20 @@
"createdAt": "2020-06-30T13:23:58.58Z",
"updatedAt": "2020-08-04T10:21:56.053Z",
"serviceBusEndpoint": "https://servicens-B.servicebus.windows.net:443/",
"status": "Active"
"status": "Active",
"geoDataReplication": {
"maxReplicationLagDurationInSeconds": "300",
"locations": [
{
"locationName": "centraluseuap",
"roleType": "Primary"
},
{
"locationName": "norwayeast",
"roleType": "Secondary"
}
]
}
},
"ResourceGroupName": "test-rg",
"Type": "Microsoft.ServiceBus/namespaces",
Expand Down Expand Up @@ -460,7 +482,7 @@
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.ServiceBus/namespaces/servicens-E",
"Identity": null,
"Kind": null,
"Location": "East US",
"Location": "italynorth",
"ManagedBy": null,
"ResourceName": "servicens-E",
"Name": "servicens-E",
Expand All @@ -475,7 +497,20 @@
"createdAt": "2020-06-30T13:23:58.58Z",
"updatedAt": "2020-08-04T10:21:56.053Z",
"serviceBusEndpoint": "https://servicens-B.servicebus.windows.net:443/",
"status": "Active"
"status": "Active",
"geoDataReplication": {
"maxReplicationLagDurationInSeconds": "300",
"locations": [
{
"locationName": "italynorth",
"roleType": "Primary"
},
{
"locationName": "spaincentral",
"roleType": "Secondary"
}
]
}
},
"ResourceGroupName": "test-rg",
"Type": "Microsoft.ServiceBus/namespaces",
Expand Down

0 comments on commit 9dfb8c5

Please sign in to comment.