diff --git a/docs/changelog.md b/docs/changelog.md index 880feb9c33..1f5e2826c3 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -34,11 +34,16 @@ See [upgrade notes][1] for helpful information when upgrading from previous vers - App Configuration: - Check that replica locations are in allowed regions by @BernieWhite. [#3441](https://github.com/Azure/PSRule.Rules.Azure/issues/3441) + - Managed Instance for Apache Cassandra: + - Check that Managed Instance for Apache Cassandra clusters have availability zones enabled by @BenjaminEngeset. + [#3592](https://github.com/Azure/PSRule.Rules.Azure/issues/3592) - Cosmos DB: - Check that Cosmos DB accounts have availability zones enabled by @BenjaminEngeset. [#3055](https://github.com/Azure/PSRule.Rules.Azure/issues/3055) - Check that MongoDB vCore clusters use Microsoft Entra ID authentication by @BenjaminEngeset. [#3369](https://github.com/Azure/PSRule.Rules.Azure/issues/3369) + - Check that MongoDB vCore clusters have availability zones enabled by @BenjaminEngeset. + [#3586](https://github.com/Azure/PSRule.Rules.Azure/issues/3586) - Data Explorer: - Check that public network access is disabled by @BenjaminEngeset. [#3114](https://github.com/Azure/PSRule.Rules.Azure/issues/3114) diff --git a/docs/en/rules/Azure.Cosmos.MongoAvailabilityZone.md b/docs/en/rules/Azure.Cosmos.MongoAvailabilityZone.md new file mode 100644 index 0000000000..5558881483 --- /dev/null +++ b/docs/en/rules/Azure.Cosmos.MongoAvailabilityZone.md @@ -0,0 +1,123 @@ +--- +reviewed: 2025-11-10 +severity: Important +pillar: Reliability +category: RE:05 Redundancy +resource: Cosmos DB +resourceType: Microsoft.DocumentDB/mongoClusters +online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.Cosmos.MongoAvailabilityZone/ +--- + +# Use zone redundant Cosmos DB MongoDB vCore clusters + +## SYNOPSIS + +Use zone redundant Cosmos DB vCore clusters in supported regions to improve reliability. + +## DESCRIPTION + +Azure Cosmos DB for MongoDB vCore clusters support zone redundancy. +When zone redundancy is enabled, your data is replicated across multiple zones within an Azure region. + +Availability zones are unique physical locations within an Azure region. +Each zone is made up of one or more datacenters equipped with independent power, cooling, and networking infrastructure. +This physical separation ensures that if one zone experiences an outage, +your Cosmos DB cluster continues to serve read and write requests from replicas in other zones without downtime. + +With zone redundancy enabled, Azure Cosmos DB provides: + +- Automatic failover between zones. +- Continuous availability during zonal failures. +- Enhanced durability by maintaining multiple copies across separate physical locations. +- Protection against datacenter-level disasters while maintaining low-latency access. + +Zone redundancy must be configured when you create a Cosmos DB cluster by setting `highAvailability.targetMode` to `ZoneRedundantPreferred`. +This setting cannot be changed after the account is created. +Zone redundancy is only available in regions that support availability zones. + +## RECOMMENDATION + +Consider configuring zone redundant high availability in locations that support availability zones to improve reliability. + +## EXAMPLES + +### Configure with Azure template + +To deploy MongoDB vCore clusters that pass this rule: + +- Set the `properties.highAvailability.targetMode` property to `ZoneRedundantPreferred`. + +For example: + +```json +{ + "type": "Microsoft.DocumentDB/mongoClusters", + "apiVersion": "2024-07-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "properties": { + "serverVersion": "8.0", + "authConfig": { + "allowedModes": [ + "MicrosoftEntraID" + ] + }, + "compute": { + "tier": "M30" + }, + "storage": { + "sizeGb": 128, + "type": "PremiumSSD" + }, + "highAvailability": { + "targetMode": "ZoneRedundantPreferred" + } + } +} +``` + +### Configure with Bicep + +To deploy MongoDB vCore clusters that pass this rule: + +- Set the `properties.highAvailability.targetMode` property to `ZoneRedundantPreferred`. + +For example: + +```bicep +resource mongoCluster 'Microsoft.DocumentDB/mongoClusters@2024-07-01' = { + name: name + location: location + properties: { + serverVersion: '8.0' + authConfig: { + allowedModes: [ + 'MicrosoftEntraID' + ] + } + compute: { + tier: 'M30' + } + storage: { + sizeGb: 128 + type: 'PremiumSSD' + } + highAvailability: { + targetMode: 'ZoneRedundantPreferred' + } + } +} +``` + +## NOTES + +This rule applies to Cosmos DB for MongoDB clusters deployed with the vCore deployment model. + +## LINKS + +- [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy) +- [Azure regions with availability zone support](https://learn.microsoft.com/azure/reliability/availability-zones-service-support) +- [Reliability: Level 1](https://learn.microsoft.com/azure/well-architected/reliability/maturity-model?tabs=level1) +- [Architecture strategies for using availability zones and regions](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones) +- [High availability in Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/azure/cosmos-db/mongodb/vcore/high-availability) +- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.documentdb/mongoclusters) diff --git a/docs/en/rules/Azure.MICassandra.AvailabilityZone.md b/docs/en/rules/Azure.MICassandra.AvailabilityZone.md new file mode 100644 index 0000000000..c901bf3619 --- /dev/null +++ b/docs/en/rules/Azure.MICassandra.AvailabilityZone.md @@ -0,0 +1,104 @@ +--- +reviewed: 2025-11-14 +severity: Important +pillar: Reliability +category: RE:05 Redundancy +resource: Managed Instance for Apache Cassandra +resourceType: Microsoft.DocumentDB/cassandraClusters,Microsoft.DocumentDB/cassandraClusters/dataCenters +online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.MICassandra.AvailabilityZone/ +--- + +# Use zone redundant Managed Instance for Apache Cassandra clusters + +## SYNOPSIS + +Use zone redundant Managed Instance for Apache Cassandra clusters in supported regions to improve reliability. + +## DESCRIPTION + +Managed Instance for Apache Cassandra supports zone redundancy through availability zones. +When availability zones are enabled, nodes are physically separated across multiple zones within an Azure region. + +Availability zones are unique physical locations within an Azure region. +Each zone is made up of one or more datacenters equipped with independent power, cooling, and networking infrastructure. +This physical separation ensures that if one zone experiences an outage, +your Cassandra cluster continues to serve read and write requests from nodes in other zones without downtime. + +With zone redundancy enabled, Managed Instance for Apache Cassandra provides: + +- Automatic distribution of nodes across zones. +- Continuous availability during zonal failures. +- Enhanced durability by maintaining multiple replicas across separate physical locations. +- Protection against datacenter-level disasters while maintaining low-latency access. + +Zone redundancy must be configured when you create a data center by setting `availabilityZone` to `true`. +This setting cannot be changed after the datacenter is created. +Zone redundancy is only available in regions that support availability zones. + +## RECOMMENDATION + +Consider enabling availability zones for data center clusters that support them to improve workload resiliency. + +## EXAMPLES + +### Configure with Azure template + +To deploy clusters that pass this rule: + +- Set `properties.availabilityZone` to `true`. + +For example: + +```json +{ + "type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "apiVersion": "2024-11-15", + "name": "[format('{0}/{1}', parameters('clusterName'), parameters('dataCenterName'))]", + "location": "[parameters('location')]", + "properties": { + "dataCenterLocation": "[parameters('location')]", + "delegatedSubnetId": "[parameters('delegatedSubnetId')]", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": true + } +} +``` + +### Configure with Bicep + +To deploy clusters that pass this rule: + +- Set `properties.availabilityZone` to `true`. + +For example: + +```bicep +resource dataCenter 'Microsoft.DocumentDB/cassandraClusters/dataCenters@2024-11-15' = { + parent: cluster + name: datacenterName + location: location + properties: { + dataCenterLocation: location + delegatedSubnetId: delegatedSubnetId + nodeCount: 3 + sku: 'Standard_E8s_v5' + diskCapacity: 4 + availabilityZone: true + } +} +``` + +## NOTES + +This rule only applies to Managed Instance for Apache Cassandra deployment model. + +## LINKS + +- [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy) +- [Azure regions with availability zone support](https://learn.microsoft.com/azure/reliability/availability-zones-service-support) +- [Reliability: Level 1](https://learn.microsoft.com/azure/well-architected/reliability/maturity-model?tabs=level1) +- [Architecture strategies for using availability zones and regions](https://learn.microsoft.com/azure/well-architected/reliability/regions-availability-zones) +- [Best practices for high availability and disaster recovery](https://learn.microsoft.com/azure/managed-instance-apache-cassandra/resilient-applications) +- [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.documentdb/cassandraclusters/datacenters) diff --git a/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 b/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 index b90bad7ff3..2aa982b189 100644 --- a/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 +++ b/src/PSRule.Rules.Azure/en/PSRule-rules.psd1 @@ -66,6 +66,8 @@ PremiumRedisCacheAvailabilityZone = "The premium redis cache ({0}) deployed to region ({1}) should use a minimum of two availability zones from the following [{2}]." EnterpriseRedisCacheAvailabilityZone = "The enterprise redis cache ({0}) deployed to region ({1}) should be zone-redundant." CosmosDBAvailabilityZone = "The Cosmos DB account ({0}) location ({1}) should have zone redundancy enabled." + MICassandraAvailabilityZone = "The Managed Instance for Apache Cassandra data center ({0}) deployed to region ({1}) should should have zone redundancy enabled." + MongoDBvCoreAvailabilityZone = "The MongoDB vCore cluster ({0}) location ({1}) should have zone redundancy enabled." AKSMinimumVersionReplace = "The configuration option 'Azure_AKSMinimumVersion' has been replaced with 'AZURE_AKS_CLUSTER_MINIMUM_VERSION'. The option 'Azure_AKSMinimumVersion' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." AKSNodeMinimumMaxPodsReplace = "The configuration option 'Azure_AKSNodeMinimumMaxPods' has been replaced with 'AZURE_AKS_POOL_MINIMUM_MAXPODS'. The option 'Azure_AKSNodeMinimumMaxPods' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." AzureAllowedRegionsReplace = "The configuration option 'Azure_AllowedRegions' has been replaced with 'AZURE_RESOURCE_ALLOWED_LOCATIONS'. The option 'Azure_AllowedRegions' is deprecated and will no longer work in the next major version. Please update your configuration to the new name. See https://aka.ms/ps-rule-azure/upgrade." diff --git a/src/PSRule.Rules.Azure/rules/Azure.Cosmos.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Azure.Cosmos.Rule.ps1 index 86ef8c6d7e..7fce566a45 100644 --- a/src/PSRule.Rules.Azure/rules/Azure.Cosmos.Rule.ps1 +++ b/src/PSRule.Rules.Azure/rules/Azure.Cosmos.Rule.ps1 @@ -32,11 +32,30 @@ Rule 'Azure.Cosmos.AvailabilityZone' -Ref 'AZR-000502' -Type 'Microsoft.Document # If the location supports availability zones, ensure zone redundancy is enabled if ($availabilityZones) { $Assert.HasFieldValue($location, 'isZoneRedundant', $true). - ReasonFrom('properties.locations', $LocalizedData.CosmosDBAvailabilityZone, $TargetObject.Name, $location.locationName); + ReasonFrom('properties.locations', $LocalizedData.CosmosDBAvailabilityZone, $TargetObject.Name, $location.locationName); } } } } + +# Synopsis: Use zone redundant Cosmos DB vCore clusters in supported regions to improve reliability. +Rule 'Azure.Cosmos.MongoAvailabilityZone' -Ref 'AZR-000503' -Type 'Microsoft.DocumentDB/mongoClusters' -Tag @{ release = 'GA'; ruleSet = '2025_12'; 'Azure.WAF/pillar' = 'Reliability'; } -Labels @{ 'Azure.WAF/maturity' = 'L1' } { + # Check for availability zones based on virtual machine scale sets, because it is not exposed through the provider for Cosmos DB. + $provider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Compute', 'virtualMachineScaleSets'); + + $location = $TargetObject.Location; + $availabilityZones = GetAvailabilityZone -Location $location -Zone $provider.ZoneMappings; + + # If the location supports availability zones, ensure zone redundancy is enabled + if ($availabilityZones) { + $Assert.HasFieldValue($TargetObject, 'properties.highAvailability.targetMode', 'ZoneRedundantPreferred'). + ReasonFrom('properties.highAvailability.targetMode', $LocalizedData.MongoDBvCoreAvailabilityZone, $TargetObject.Name, $location); + } + else { + # Pass if the region does not support availability zones + $Assert.Pass(); + } +} #endregion Rules #region Helper functions diff --git a/src/PSRule.Rules.Azure/rules/Azure.MICassandra.Rule.ps1 b/src/PSRule.Rules.Azure/rules/Azure.MICassandra.Rule.ps1 new file mode 100644 index 0000000000..47d937711e --- /dev/null +++ b/src/PSRule.Rules.Azure/rules/Azure.MICassandra.Rule.ps1 @@ -0,0 +1,56 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# +# Validation rules for Azure Managed Instance for Apache Cassandra +# + +#region Rules + +# Synopsis: Use zone redundant Azure Managed Instance for Apache Cassandra clusters in supported regions to improve reliability. +Rule 'Azure.MICassandra.AvailabilityZone' -Ref 'AZR-000504' -Type 'Microsoft.DocumentDB/cassandraClusters', 'Microsoft.DocumentDB/cassandraClusters/dataCenters' -Tag @{ release = 'GA'; ruleSet = '2025_12'; 'Azure.WAF/pillar' = 'Reliability'; } -Labels @{ 'Azure.WAF/maturity' = 'L1' } { + # Check for availability zones based on virtual machine scale sets, because it is not exposed through the provider for Managed Instance for Apache Cassandra. + $provider = [PSRule.Rules.Azure.Runtime.Helper]::GetResourceType('Microsoft.Compute', 'virtualMachineScaleSets') + + $dataCenters = @(GetCassandraDataCenter) + if ($dataCenters.Count -eq 0) { + return $Assert.Pass() + } + + foreach ($dataCenter in $dataCenters) { + $availabilityZones = GetAvailabilityZone -Location $dataCenter.properties.dataCenterLocation -Zone $provider.ZoneMappings + + if ($availabilityZones) { + $Assert.HasFieldValue($dataCenter, 'properties.availabilityZone', $true). + ReasonFrom( + 'properties.availabilityZone', + $LocalizedData.MICassandraAvailabilityZone, + $dataCenter.name, + $dataCenter.properties.dataCenterLocation + ) + } + # Don't flag if the region does not support availability zones. + else { + $Assert.Pass() + } + } +} + +#endregion Rules + +#region Helper functions + +function global:GetCassandraDataCenter { + [CmdletBinding()] + param () + process { + if ($PSRule.TargetType -eq 'Microsoft.DocumentDB/cassandraClusters') { + GetSubResources -ResourceType 'Microsoft.DocumentDB/cassandraClusters/dataCenters' + } + elseif ($PSRule.TargetType -eq 'Microsoft.DocumentDB/cassandraClusters/dataCenters') { + $TargetObject + } + } +} + +#endregion Helper functions diff --git a/tests/PSRule.Rules.Azure.Tests/Azure.Cosmos.Tests.ps1 b/tests/PSRule.Rules.Azure.Tests/Azure.Cosmos.Tests.ps1 index a7e0991bc1..5e2a8a0099 100644 --- a/tests/PSRule.Rules.Azure.Tests/Azure.Cosmos.Tests.ps1 +++ b/tests/PSRule.Rules.Azure.Tests/Azure.Cosmos.Tests.ps1 @@ -135,8 +135,8 @@ Describe 'Azure.Cosmos' -Tag 'Cosmos', 'CosmosDB' { # Pass $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); - $ruleResult.Length | Should -Be 2; - $ruleResult.TargetName | Should -BeIn 'mongodb-b', 'mongodb-c'; + $ruleResult.Length | Should -Be 4; + $ruleResult.TargetName | Should -BeIn 'mongodb-b', 'mongodb-c', 'mongodb-d', 'mongodb-e'; } It 'Azure.Cosmos.AvailabilityZone' { @@ -155,6 +155,24 @@ Describe 'Azure.Cosmos' -Tag 'Cosmos', 'CosmosDB' { $ruleResult.Length | Should -Be 5; $ruleResult.TargetName | Should -BeIn 'graph-A', 'graph-B', 'nosql-C', 'nosql-D', 'nosql-E'; } + + It 'Azure.Cosmos.MongoAvailabilityZone' { + $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.Cosmos.MongoAvailabilityZone' }; + + # Fail + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' } | Sort-Object TargetName); + $ruleResult.Length | Should -Be 3; + $ruleResult.TargetName | Should -BeIn 'mongodb-a', 'mongodb-b', 'mongodb-c'; + + $ruleResult[0].Reason | Should -Be "Path properties.highAvailability.targetMode: The MongoDB vCore cluster (mongodb-a) location (East US) should have zone redundancy enabled."; + $ruleResult[1].Reason | Should -Be "Path properties.highAvailability.targetMode: The MongoDB vCore cluster (mongodb-b) location (East US) should have zone redundancy enabled."; + $ruleResult[2].Reason | Should -Be "Path properties.highAvailability.targetMode: The MongoDB vCore cluster (mongodb-c) location (East US) should have zone redundancy enabled."; + + # Pass + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); + $ruleResult.Length | Should -Be 2; + $ruleResult.TargetName | Should -BeIn 'mongodb-d', 'mongodb-e'; + } } Context 'Resource name - Azure.Cosmos.AccountName' { diff --git a/tests/PSRule.Rules.Azure.Tests/Azure.MICassandra.Tests.ps1 b/tests/PSRule.Rules.Azure.Tests/Azure.MICassandra.Tests.ps1 new file mode 100644 index 0000000000..c10ba4eb78 --- /dev/null +++ b/tests/PSRule.Rules.Azure.Tests/Azure.MICassandra.Tests.ps1 @@ -0,0 +1,57 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# +# Unit tests for Azure Managed Instance for Apache Cassandra 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.MICassandra' -Tag 'MICassandra', 'ManagedCassandra' { + Context 'Conditions' { + BeforeAll { + $invokeParams = @{ + Baseline = 'Azure.All' + Module = 'PSRule.Rules.Azure' + WarningAction = 'Ignore' + ErrorAction = 'Stop' + } + $dataPath = Join-Path -Path $here -ChildPath 'Resources.MICassandra.json'; + $result = Invoke-PSRule @invokeParams -InputPath $dataPath; + } + + It 'Azure.MICassandra.AvailabilityZone' { + $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.MICassandra.AvailabilityZone' }; + + # Fail + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' } | Sort-Object TargetName); + $ruleResult.Length | Should -Be 3; + $ruleResult.TargetName | Should -BeIn 'micassandra-b', 'micassandra-c', 'micassandra-f/datacenter-a'; + + $ruleResult[0].Reason | Should -Be "Path properties.availabilityZone: The Managed Instance for Apache Cassandra data center (datacenter-a) deployed to region (westus2) should should have zone redundancy enabled."; + $ruleResult[1].Reason | Should -Be "Path properties.availabilityZone: The Managed Instance for Apache Cassandra data center (datacenter-b) deployed to region (eastus) should should have zone redundancy enabled."; + $ruleResult[2].Reason | Should -Be "Path properties.availabilityZone: The Managed Instance for Apache Cassandra data center (micassandra-f/datacenter-a) deployed to region (westus2) should should have zone redundancy enabled."; + + # Pass + $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); + $ruleResult.Length | Should -Be 6; + $ruleResult.TargetName | Should -BeIn 'micassandra-a', 'micassandra-d', 'micassandra-e', 'micassandra-f', 'micassandra-e/datacenter-a', 'micassandra-g/datacenter-a'; + } + } +} diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.Cosmos.json b/tests/PSRule.Rules.Azure.Tests/Resources.Cosmos.json index 6080beee4e..1602b09914 100644 --- a/tests/PSRule.Rules.Azure.Tests/Resources.Cosmos.json +++ b/tests/PSRule.Rules.Azure.Tests/Resources.Cosmos.json @@ -480,6 +480,42 @@ "sharding": { "shardCount": 3 }, + "backup": {}, + "publicNetworkAccess": "Disabled", + "dataApi": { + "mode": "Disabled" + }, + "createMode": "Default" + }, + "ResourceGroupName": "rg-test", + "Type": "Microsoft.DocumentDB/mongoClusters", + "ResourceType": "Microsoft.DocumentDB/mongoClusters", + "Tags": null, + "SubscriptionId": "00000000-0000-0000-0000-000000000000" + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.DocumentDB/mongoClusters/mongodb-d", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.DocumentDB/mongoClusters/mongodb-d", + "Location": "East US", + "ResourceName": "mongodb-d", + "Name": "mongodb-d", + "Properties": { + "serverVersion": "8.0", + "authConfig": { + "allowedModes": [ + "MicrosoftEntraID" + ] + }, + "compute": { + "tier": "M30" + }, + "storage": { + "sizeGb": 128, + "type": "PremiumSSD" + }, + "sharding": { + "shardCount": 1 + }, "highAvailability": { "targetMode": "ZoneRedundantPreferred" }, @@ -496,6 +532,45 @@ "Tags": null, "SubscriptionId": "00000000-0000-0000-0000-000000000000" }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.DocumentDB/mongoClusters/mongodb-e", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.DocumentDB/mongoClusters/mongodb-e", + "Location": "West US", + "ResourceName": "mongodb-e", + "Name": "mongodb-e", + "Properties": { + "serverVersion": "8.0", + "authConfig": { + "allowedModes": [ + "MicrosoftEntraID" + ] + }, + "compute": { + "tier": "M30" + }, + "storage": { + "sizeGb": 128, + "type": "PremiumSSD" + }, + "sharding": { + "shardCount": 1 + }, + "highAvailability": { + "targetMode": "Disabled" + }, + "backup": {}, + "publicNetworkAccess": "Disabled", + "dataApi": { + "mode": "Disabled" + }, + "createMode": "Default" + }, + "ResourceGroupName": "rg-test", + "Type": "Microsoft.DocumentDB/mongoClusters", + "ResourceType": "Microsoft.DocumentDB/mongoClusters", + "Tags": null, + "SubscriptionId": "00000000-0000-0000-0000-000000000000" + }, { "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.DocumentDB/databaseAccounts/nosql-D", "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-test/providers/Microsoft.DocumentDB/databaseAccounts/nosql-D", diff --git a/tests/PSRule.Rules.Azure.Tests/Resources.MICassandra.json b/tests/PSRule.Rules.Azure.Tests/Resources.MICassandra.json new file mode 100644 index 0000000000..386888d785 --- /dev/null +++ b/tests/PSRule.Rules.Azure.Tests/Resources.MICassandra.json @@ -0,0 +1,310 @@ +[ + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-a", + "ResourceName": "micassandra-a", + "Name": "micassandra-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westus2", + "Tags": {}, + "Properties": { + "delegatedManagementSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "cassandraVersion": "4.0", + "clusterNameOverride": "micassandra-a", + "authenticationMethod": "Cassandra", + "initialCassandraAdminPassword": "Password123!", + "provisioningState": "Succeeded" + }, + "resources": [ + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-a/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-a/dataCenters/datacenter-a", + "ResourceName": "datacenter-a", + "Name": "datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westus2", + "Properties": { + "dataCenterLocation": "westus2", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": true, + "provisioningState": "Succeeded" + } + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-a/dataCenters/datacenter-b", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-a/dataCenters/datacenter-b", + "ResourceName": "datacenter-b", + "Name": "datacenter-b", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "eastus", + "Properties": { + "dataCenterLocation": "eastus", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": true, + "provisioningState": "Succeeded" + } + } + ] + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-b", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-b", + "ResourceName": "micassandra-b", + "Name": "micassandra-b", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westus2", + "Tags": {}, + "Properties": { + "delegatedManagementSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "cassandraVersion": "4.0", + "clusterNameOverride": "micassandra-b", + "authenticationMethod": "Cassandra", + "initialCassandraAdminPassword": "Password123!", + "provisioningState": "Succeeded" + }, + "resources": [ + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-b/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-b/dataCenters/datacenter-a", + "ResourceName": "datacenter-a", + "Name": "datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westus2", + "Properties": { + "dataCenterLocation": "westus2", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": false, + "provisioningState": "Succeeded" + } + } + ] + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-c", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-c", + "ResourceName": "micassandra-c", + "Name": "micassandra-c", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "eastus", + "Tags": {}, + "Properties": { + "delegatedManagementSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "cassandraVersion": "4.0", + "clusterNameOverride": "micassandra-c", + "authenticationMethod": "Cassandra", + "initialCassandraAdminPassword": "Password123!", + "provisioningState": "Succeeded" + }, + "resources": [ + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-c/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-c/dataCenters/datacenter-a", + "ResourceName": "datacenter-a", + "Name": "datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "eastus", + "Properties": { + "dataCenterLocation": "eastus", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": true, + "provisioningState": "Succeeded" + } + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-c/dataCenters/datacenter-b", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-c/dataCenters/datacenter-b", + "ResourceName": "datacenter-b", + "Name": "datacenter-b", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "eastus", + "Properties": { + "dataCenterLocation": "eastus", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": false, + "provisioningState": "Succeeded" + } + } + ] + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-d", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-d", + "ResourceName": "micassandra-d", + "Name": "micassandra-d", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westindia", + "Tags": {}, + "Properties": { + "delegatedManagementSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "cassandraVersion": "4.0", + "clusterNameOverride": "micassandra-d", + "authenticationMethod": "Cassandra", + "initialCassandraAdminPassword": "Password123!", + "provisioningState": "Succeeded" + }, + "resources": [ + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-d/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-d/dataCenters/datacenter-a", + "ResourceName": "datacenter-a", + "Name": "datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westindia", + "Properties": { + "dataCenterLocation": "westindia", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": false, + "provisioningState": "Succeeded" + } + } + ] + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-e", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-e", + "ResourceName": "micassandra-e", + "Name": "micassandra-e", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "eastus", + "Tags": {}, + "Properties": { + "delegatedManagementSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "cassandraVersion": "4.0", + "clusterNameOverride": "micassandra-e", + "authenticationMethod": "Cassandra", + "initialCassandraAdminPassword": "Password123!", + "provisioningState": "Succeeded" + } + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-f", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-f", + "ResourceName": "micassandra-f", + "Name": "micassandra-f", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westus2", + "Tags": {}, + "Properties": { + "delegatedManagementSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "cassandraVersion": "4.0", + "clusterNameOverride": "micassandra-f", + "authenticationMethod": "Cassandra", + "initialCassandraAdminPassword": "Password123!", + "provisioningState": "Succeeded" + } + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-e/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-e/dataCenters/datacenter-a", + "ResourceName": "micassandra-e/datacenter-a", + "Name": "micassandra-e/datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "eastus", + "Properties": { + "dataCenterLocation": "eastus", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": true, + "provisioningState": "Succeeded" + } + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-f/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-f/dataCenters/datacenter-a", + "ResourceName": "micassandra-f/datacenter-a", + "Name": "micassandra-f/datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westus2", + "Properties": { + "dataCenterLocation": "westus2", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": false, + "provisioningState": "Succeeded" + } + }, + { + "ResourceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-g/dataCenters/datacenter-a", + "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.DocumentDB/cassandraClusters/micassandra-g/dataCenters/datacenter-a", + "ResourceName": "micassandra-g/datacenter-a", + "Name": "micassandra-g/datacenter-a", + "ResourceGroupName": "test-rg", + "Type": "Microsoft.DocumentDB/cassandraClusters/dataCenters", + "ApiVersion": "2024-11-15", + "SubscriptionId": "00000000-0000-0000-0000-000000000000", + "Location": "westindia", + "Properties": { + "dataCenterLocation": "westindia", + "delegatedSubnetId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/vnet-test/subnets/subnet-test", + "nodeCount": 3, + "sku": "Standard_E8s_v5", + "diskCapacity": 4, + "availabilityZone": false, + "provisioningState": "Succeeded" + } + } +]