Skip to content

Commit

Permalink
feat(new): Added Azure.LogAnalytics.Replication (Azure#2894)
Browse files Browse the repository at this point in the history
* feat(new): Added Azure.LogAnalytics.Replication

* feat: Feedback from code review
  • Loading branch information
BenjaminEngeset authored May 30, 2024
1 parent cb44eea commit 0e8ad12
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 0 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:
- Log Analytics:
- Check that workspaces have workspace replication enabled by @BenjaminEngeset.
[#2893](https://github.com/Azure/PSRule.Rules.Azure/issues/2893)

## v1.37.0-B0034 (pre-release)

What's changed since pre-release v1.37.0-B0009:
Expand Down
106 changes: 106 additions & 0 deletions docs/en/rules/Azure.LogAnalytics.Replication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
severity: Important
pillar: Reliability
category: RE:05 Regions and availability zones
resource: Log Analytics
online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.LogAnalytics.Replication/
---

# Replicate workspaces across regions

## SYNOPSIS

Log Analytics workspaces should have workspace replication enabled to improve service availability.

## DESCRIPTION

In the event of a service disruption, access to monitoring data and collection of new data in a workspace may be temporarily impacted.

Log Analytics workspaces support replication of monitoring data to a workspace to a secondary region.
When relication is enabled, new monitoring data is replicated to the secondary region in addition to the primary region.
Failover to the workspace in the secondary region can be triggered manually.

Some limitations apply:

- Failover occurs by updating DNS records to point to the secondary region.
As a result, failover won't occur immediately and clients with open connections won't update until a new connection is established.
- Failover is a customer initiated action.
Failover to the secondard region does not occur automatically.
- Data collection rules need to be updated to point to the system data collection endpoint for ingested data to be replicated.
- See documentation references below for additional limitations and important information.

## RECOMMENDATION

Consider replicating Log Analytics workspaces across regions to improve access to monitoring data in the event of a regional service disruption.

## EXAMPLES

### Configure with Azure template

To deploy Log Analytics workspaces that pass this rule:

- Set the `properties.replication.enabled` property to `true`.
- Set the `properties.replication.location` property to a supported region in the same region group as the workspace primary region.

For example:

```json
{
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2023-01-01-preview",
"name": "[parameters('name')]",
"location": "westeurope",
"properties": {
"replication": {
"enabled": true,
"location": "northeurope"
},
"publicNetworkAccessForIngestion": "Enabled",
"publicNetworkAccessForQuery": "Enabled",
"retentionInDays": 30,
"sku": {
"name": "PERGB2018"
}
}
}
```

### Configure with Bicep

To deploy Log Analytics workspaces that pass this rule:

- Set the `properties.replication.enabled` property to `true`.
- Set the `properties.replication.location` property to a supported region in the same region group as the workspace primary region.

For example:

```bicep
resource workspace 'Microsoft.OperationalInsights/workspaces@2023-01-01-preview' = {
name: name
location: 'westeurope'
properties: {
replication: {
enabled: true
location: 'northeurope'
}
publicNetworkAccessForIngestion: 'Enabled'
publicNetworkAccessForQuery: 'Enabled'
retentionInDays: 30
sku: {
name: 'PERGB2018'
}
}
}
```

## NOTES

This feature for Log Analytics workspaces is currently in preview.

Replication of Log Analytics workspaces linked to a dedicated cluster is currently not supported.

## LINKS

- [RE:05 Regions and availability zones](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones)
- [Replicate workspace across regions](https://learn.microsoft.com/azure/azure-monitor/logs/workspace-replication)
- [Azure resource deployment](https://learn.microsoft.com/azure/templates/microsoft.operationalinsights/workspaces)
34 changes: 34 additions & 0 deletions src/PSRule.Rules.Azure/rules/Azure.LogAnalytics.Rule.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

#
# Rules for Log Analytics
#

#region Rules

---
# Synopsis: Log Analytics workspaces should have workspace replication enabled to improve service availability.
apiVersion: github.com/microsoft/PSRule/v1
kind: Rule
metadata:
name: Azure.LogAnalytics.Replication
ref: AZR-000425
tags:
release: preview
ruleSet: 2024_06
Azure.WAF/pillar: Reliability
spec:
type:
- Microsoft.OperationalInsights/workspaces
where:
field: properties.features.clusterResourceId
hasValue: false
condition:
allOf:
- field: properties.replication.enabled
equals: true
- field: properties.replication.location
hasValue: true

#endregion Rules
57 changes: 57 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Azure.LogAnalytics.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

#
# Unit tests for Log Analytics rules
#

[CmdletBinding()]
param ()

BeforeAll {
# Setup error handling
$ErrorActionPreference = 'Stop';
Set-StrictMode -Version latest;

if ($Env:SYSTEM_DEBUG -eq 'true') {
$VerbosePreference = 'Continue';
}

# Setup tests paths
$rootPath = $PWD;
Import-Module (Join-Path -Path $rootPath -ChildPath out/modules/PSRule.Rules.Azure) -Force;
$here = (Resolve-Path $PSScriptRoot).Path;
}

Describe 'Azure.LogAnalytics' -Tag 'LogAnalytics' {
Context 'Conditions' {
BeforeAll {
$invokeParams = @{
Baseline = 'Azure.All'
Module = 'PSRule.Rules.Azure'
WarningAction = 'Ignore'
ErrorAction = 'Stop'
}
$dataPath = Join-Path -Path $here -ChildPath 'Resources.LogAnalytics.json';
$result = Invoke-PSRule @invokeParams -InputPath $dataPath;
}

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

# Fail
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' });
$ruleResult.Length | Should -Be 3;
$ruleResult.TargetName | Should -Be 'workspace-a', 'workspace-b', 'workspace-c';

$ruleResult[0].Reason | Should -Be "Path properties.replication.enabled: The field 'properties.replication.enabled' does not exist.";
$ruleResult[1].Reason | Should -Be "Path properties.replication.enabled: Is set to 'False'.";
$ruleResult[2].Reason | Should -Be "Path properties.replication.location: The field 'properties.replication.location' does not exist.";

# Pass
$ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' });
$ruleResult.Length | Should -Be 1;
$ruleResult.TargetName | Should -Be 'workspace-d';
}
}
}
137 changes: 137 additions & 0 deletions tests/PSRule.Rules.Azure.Tests/Resources.LogAnalytics.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
[
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-a",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-a",
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2023-01-01-preview",
"name": "workspace-a",
"location": "westus",
"tags": {
"Resource": "Log Analytics Workspace"
},
"identity": {
"type": "string",
"userAssignedIdentities": {}
},
"properties": {
"features": {
"disableLocalAuth": false,
"enableLogAccessUsingOnlyResourcePermissions": false,
"immediatePurgeDataOn30Days": true
},
"publicNetworkAccessForIngestion": "Enabled",
"publicNetworkAccessForQuery": "Enabled",
"retentionInDays": 30,
"sku": {
"name": "PERGB2018"
},
"workspaceCapping": {
"dailyQuotaGb": -1
}
}
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-b",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-b",
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2023-01-01-preview",
"name": "workspace-b",
"location": "westeurope",
"tags": {
"Resource": "Log Analytics Workspace"
},
"identity": {
"type": "string",
"userAssignedIdentities": {}
},
"properties": {
"features": {
"disableLocalAuth": false,
"enableLogAccessUsingOnlyResourcePermissions": false,
"immediatePurgeDataOn30Days": true
},
"replication": {
"enabled": false,
"location": "northeurope"
},
"publicNetworkAccessForIngestion": "Enabled",
"publicNetworkAccessForQuery": "Enabled",
"retentionInDays": 30,
"sku": {
"name": "PERGB2018"
},
"workspaceCapping": {
"dailyQuotaGb": -1
}
}
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-c",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-c",
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2023-01-01-preview",
"name": "workspace-c",
"location": "westeurope",
"tags": {
"Resource": "Log Analytics Workspace"
},
"identity": {
"type": "string",
"userAssignedIdentities": {}
},
"properties": {
"features": {
"disableLocalAuth": false,
"enableLogAccessUsingOnlyResourcePermissions": false,
"immediatePurgeDataOn30Days": true
},
"replication": {
"enabled": true
},
"publicNetworkAccessForIngestion": "Enabled",
"publicNetworkAccessForQuery": "Enabled",
"retentionInDays": 30,
"sku": {
"name": "PERGB2018"
},
"workspaceCapping": {
"dailyQuotaGb": -1
}
}
},
{
"ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-d",
"Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspace/workspace-d",
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2023-01-01-preview",
"name": "workspace-d",
"location": "westeurope",
"tags": {
"Resource": "Log Analytics Workspace"
},
"identity": {
"type": "string",
"userAssignedIdentities": {}
},
"properties": {
"features": {
"disableLocalAuth": false,
"enableLogAccessUsingOnlyResourcePermissions": false,
"immediatePurgeDataOn30Days": true
},
"replication": {
"enabled": true,
"location": "northeurope"
},
"publicNetworkAccessForIngestion": "Enabled",
"publicNetworkAccessForQuery": "Enabled",
"retentionInDays": 30,
"sku": {
"name": "PERGB2018"
},
"workspaceCapping": {
"dailyQuotaGb": -1
}
}
}
]

0 comments on commit 0e8ad12

Please sign in to comment.