forked from Azure/PSRule.Rules.Azure
-
Notifications
You must be signed in to change notification settings - Fork 0
Add zone redundancy rule for Event Hub namespaces (AZR-000505) #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
781a1a3
Initial plan
Copilot 8e6c2d0
Add EventHub zone redundancy rule (AZR-000503)
Copilot 254ce10
Update rule reference to AZR-000505
Copilot b9f250b
Add complete test coverage for all AZ scenarios
Copilot 3b5708d
Reorganize test data: failing cases (a-b) first, then passing (c-h)
Copilot c3ba923
Remove index.md changes (auto-generated file)
Copilot 1e9995d
Update reviewed date to 2025-11-19
Copilot 0eec3d7
Apply missing documentation updates from review feedback
Copilot 2fbce22
Restore network rule set resource for hubns-D
Copilot 9252911
Use -BeExactly for reason assertions in AvailabilityZone test
Copilot 600ac56
Add blank line before reason assertions for better readability
Copilot 81c26b5
Merge branch 'main' into copilot/create-new-rule
BenjaminEngeset 08cc124
Bump github/codeql-action from 4.31.3 to 4.31.4 (#3600)
dependabot[bot] 887b28f
Updates
BernieWhite cdfa487
Merge branch 'main' into copilot/create-new-rule
BernieWhite 4a713aa
Bump rule ID for open PRs
BernieWhite 89e7afd
Bump actions/checkout from 5.0.0 to 6.0.0 (#3604)
dependabot[bot] 92b0417
Merge branch 'main' into copilot/create-new-rule
BenjaminEngeset File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| --- | ||
| reviewed: 2025-11-19 | ||
| severity: Important | ||
| pillar: Reliability | ||
| category: RE:05 Redundancy | ||
| resource: Event Hub | ||
| resourceType: Microsoft.EventHub/namespaces | ||
| online version: https://azure.github.io/PSRule.Rules.Azure/en/rules/Azure.EventHub.AvailabilityZone/ | ||
| --- | ||
|
|
||
| # Use zone redundant Event Hub namespaces | ||
|
|
||
| ## SYNOPSIS | ||
|
|
||
| Use zone redundant Event Hub namespaces in supported regions to improve reliability. | ||
|
|
||
| ## DESCRIPTION | ||
|
|
||
| Azure Event Hubs supports zone redundancy to provide enhanced resiliency and high availability. | ||
| When zone redundancy is enabled, Event Hubs automatically replicates namespace metadata | ||
| and event data across multiple availability zones within a 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. | ||
| This physical separation protects your Event Hubs namespace from zone-level failures, | ||
| ensuring continuous availability even if an entire availability zone experiences an outage. | ||
|
|
||
| With zone redundancy enabled, Azure Event Hubs provides: | ||
|
|
||
| - Synchronous replication of metadata and events across zones. | ||
| - Continuous availability during zonal failures. | ||
| - Protection against datacenter-level disasters while maintaining low-latency access. | ||
|
|
||
| Zone redundancy must be configured when you create an Event Hub namespace by setting `zoneRedundant` to `true`. | ||
| This setting cannot be changed after the namespace is created. | ||
| Zone redundancy is only available in regions that support availability zones. | ||
|
|
||
| ## RECOMMENDATION | ||
|
|
||
| Consider using using a minimum of Standard Event Hub namespaces configured with zone redundancy to improve workload resiliency. | ||
|
|
||
| ## EXAMPLES | ||
|
|
||
| ### Configure with Azure template | ||
|
|
||
| To deploy Event Hub namespaces that pass this rule: | ||
|
|
||
| - Set the `properties.zoneRedundant` property to `true`. | ||
|
|
||
| For example: | ||
|
|
||
| ```json | ||
| { | ||
| "type": "Microsoft.EventHub/namespaces", | ||
| "apiVersion": "2024-01-01", | ||
| "name": "[parameters('name')]", | ||
| "location": "[parameters('location')]", | ||
| "sku": { | ||
| "name": "Standard", | ||
| "tier": "Standard" | ||
| }, | ||
| "properties": { | ||
| "disableLocalAuth": true, | ||
| "minimumTlsVersion": "1.2", | ||
| "zoneRedundant": true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### Configure with Bicep | ||
|
|
||
| To deploy Event Hub namespaces that pass this rule: | ||
|
|
||
| - Set the `properties.zoneRedundant` property to `true`. | ||
|
|
||
| For example: | ||
|
|
||
| ```bicep | ||
| resource eventHubNamespace 'Microsoft.EventHub/namespaces@2024-01-01' = { | ||
| name: name | ||
| location: location | ||
| sku: { | ||
| name: 'Standard' | ||
| tier: 'Standard' | ||
| } | ||
| properties: { | ||
| disableLocalAuth: true | ||
| minimumTlsVersion: '1.2' | ||
| zoneRedundant: true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| <!-- external:avm avm/res/event-hub/namespace zoneRedundant --> | ||
|
|
||
| ## NOTES | ||
BenjaminEngeset marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Availability zones is supported on Standard, Premium, and Dedicated tiers. | ||
|
|
||
| For the Dedicated tier, availability zones require a minimum of three capacity units (CUs). | ||
|
|
||
| ## LINKS | ||
|
|
||
| - [RE:05 Redundancy](https://learn.microsoft.com/azure/well-architected/reliability/redundancy) | ||
| - [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) | ||
| - [Azure regions with availability zone support](https://learn.microsoft.com/azure/reliability/availability-zones-service-support) | ||
| - [High availability with Azure Event Hubs](https://learn.microsoft.com/azure/reliability/reliability-event-hubs) | ||
| - [Azure deployment reference](https://learn.microsoft.com/azure/templates/microsoft.eventhub/namespaces) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -42,8 +42,8 @@ Describe 'Azure.EventHub' -Tag 'EventHub' { | |||||||||||||
| # Fail | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); | ||||||||||||||
| $ruleResult | Should -Not -BeNullOrEmpty; | ||||||||||||||
| $ruleResult.Length | Should -Be 5; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-B', 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F'; | ||||||||||||||
| $ruleResult.Length | Should -Be 7; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-B', 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F', 'hubns-G', 'hubns-H'; | ||||||||||||||
|
|
||||||||||||||
| # Pass | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); | ||||||||||||||
|
|
@@ -58,8 +58,8 @@ Describe 'Azure.EventHub' -Tag 'EventHub' { | |||||||||||||
| # Fail | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); | ||||||||||||||
| $ruleResult | Should -Not -BeNullOrEmpty; | ||||||||||||||
| $ruleResult.Length | Should -Be 5; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-B', 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F'; | ||||||||||||||
| $ruleResult.Length | Should -Be 7; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-B', 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F', 'hubns-G', 'hubns-H'; | ||||||||||||||
|
|
||||||||||||||
| # Pass | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); | ||||||||||||||
|
|
@@ -82,8 +82,8 @@ Describe 'Azure.EventHub' -Tag 'EventHub' { | |||||||||||||
| # Pass | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); | ||||||||||||||
| $ruleResult | Should -Not -BeNullOrEmpty; | ||||||||||||||
| $ruleResult.Length | Should -Be 4; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F'; | ||||||||||||||
| $ruleResult.Length | Should -Be 6; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F', 'hubns-G', 'hubns-H'; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| It 'Azure.EventHub.Firewall' { | ||||||||||||||
|
|
@@ -92,17 +92,35 @@ Describe 'Azure.EventHub' -Tag 'EventHub' { | |||||||||||||
| # Fail | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); | ||||||||||||||
| $ruleResult.Length | Should -Be 4; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-B', 'hubns-C', 'hubns-D', 'default-A'; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-B', 'hubns-C', 'hubns-D', 'hubns-X/default-A'; | ||||||||||||||
|
|
||||||||||||||
| $ruleResult[0].Reason | Should -BeExactly "Path properties.publicNetworkAccess: Does not exist."; | ||||||||||||||
| $ruleResult[1].Reason | Should -BeIn "Path properties.publicNetworkAccess: Is set to 'Enabled'."; | ||||||||||||||
| $ruleResult[2..3].Reason | Should -BeIn "Path properties.publicNetworkAccess: Is set to 'Enabled'.", "Path properties.defaultAction: Is set to 'Allow'." | ||||||||||||||
|
|
||||||||||||||
| # Pass | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); | ||||||||||||||
| $ruleResult.Length | Should -Be 7; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-E', 'hubns-F', 'hubns-Y/default-B', 'default-C', 'default-D', 'hubns-G', 'hubns-H'; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| It 'Azure.EventHub.AvailabilityZone' { | ||||||||||||||
| $filteredResult = $result | Where-Object { $_.RuleName -eq 'Azure.EventHub.AvailabilityZone' }; | ||||||||||||||
|
|
||||||||||||||
| $ruleResult[0].Reason | Should -BeExactly "Path properties.publicNetworkAccess: Does not exist." | ||||||||||||||
| $ruleResult[1].Reason | Should -BeExactly "Path properties.publicNetworkAccess: Is set to 'Enabled'." | ||||||||||||||
| $ruleResult[2].Reason | Should -BeIn "Path properties.publicNetworkAccess: Is set to 'Enabled'.", "Path properties.defaultAction: Is set to 'Allow'." | ||||||||||||||
| $ruleResult[3].Reason | Should -BeIn "Path properties.publicNetworkAccess: Is set to 'Enabled'.", "Path properties.defaultAction: Is set to 'Allow'." | ||||||||||||||
| # Fail | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Fail' }); | ||||||||||||||
| $ruleResult | Should -Not -BeNullOrEmpty; | ||||||||||||||
| $ruleResult.Length | Should -Be 2; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-A', 'hubns-B'; | ||||||||||||||
|
|
||||||||||||||
| $ruleResult[0].Reason | Should -BeExactly "Path properties.zoneRedundant: Does not exist."; | ||||||||||||||
| $ruleResult[1].Reason | Should -BeExactly "Path properties.zoneRedundant: Is set to 'False'."; | ||||||||||||||
|
|
||||||||||||||
|
Comment on lines
116
to
118
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @copilot one down
Suggested change
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Applied in commit 600ac56. |
||||||||||||||
| # Pass | ||||||||||||||
| $ruleResult = @($filteredResult | Where-Object { $_.Outcome -eq 'Pass' }); | ||||||||||||||
| $ruleResult.Length | Should -Be 5; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-E', 'hubns-F', 'default-B', 'default-C', 'default-D'; | ||||||||||||||
| $ruleResult | Should -Not -BeNullOrEmpty; | ||||||||||||||
| $ruleResult.Length | Should -Be 6; | ||||||||||||||
| $ruleResult.TargetName | Should -BeIn 'hubns-C', 'hubns-D', 'hubns-E', 'hubns-F', 'hubns-G', 'hubns-H'; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.