diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8beea05f83..95530b1604 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -51,7 +51,7 @@ /avm/res/event-grid/domain/ @Azure/avm-res-eventgrid-domain-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/event-grid/system-topic/ @Azure/avm-res-eventgrid-systemtopic-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/event-grid/topic/ @Azure/avm-res-eventgrid-topic-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/event-hub/namespace/ @Azure/avm-res-eventhub-namespace-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/event-hub/namespace/ @Azure/avm-res-eventhub-namespace-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/health-bot/health-bot/ @Azure/avm-res-healthbot-healthbot-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/healthcare-apis/workspace/ @Azure/avm-res-healthcareapis-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/insights/action-group/ @Azure/avm-res-insights-actiongroup-module-owners-bicep @Azure/avm-core-team-technical-bicep diff --git a/.github/ISSUE_TEMPLATE/avm_module_issue.yml b/.github/ISSUE_TEMPLATE/avm_module_issue.yml index aa062af956..eb9a62a373 100644 --- a/.github/ISSUE_TEMPLATE/avm_module_issue.yml +++ b/.github/ISSUE_TEMPLATE/avm_module_issue.yml @@ -85,7 +85,7 @@ body: - "avm/res/event-grid/domain" - "avm/res/event-grid/system-topic" - "avm/res/event-grid/topic" - # - "avm/res/event-hub/namespace" + - "avm/res/event-hub/namespace" - "avm/res/health-bot/health-bot" # - "avm/res/healthcare-apis/workspace" - "avm/res/insights/action-group" diff --git a/.github/workflows/avm.res.event-hub.namespace.yml b/.github/workflows/avm.res.event-hub.namespace.yml new file mode 100644 index 0000000000..fd751cc11d --- /dev/null +++ b/.github/workflows/avm.res.event-hub.namespace.yml @@ -0,0 +1,85 @@ +name: "avm.res.event-hub.namespace" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.event-hub.namespace.yml" + - "avm/res/event-hub/namespace/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/event-hub/namespace" + workflowPath: ".github/workflows/avm.res.event-hub.namespace.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-latest + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + permissions: + id-token: write # For OIDC + contents: write # For release tags + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/avm/res/event-hub/namespace/README.md b/avm/res/event-hub/namespace/README.md new file mode 100644 index 0000000000..984140f5c2 --- /dev/null +++ b/avm/res/event-hub/namespace/README.md @@ -0,0 +1,1834 @@ +# Event Hub Namespaces `[Microsoft.EventHub/namespaces]` + +This module deploys an Event Hub Namespace. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.EventHub/namespaces` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces) | +| `Microsoft.EventHub/namespaces/authorizationRules` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/authorizationRules) | +| `Microsoft.EventHub/namespaces/disasterRecoveryConfigs` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/disasterRecoveryConfigs) | +| `Microsoft.EventHub/namespaces/eventhubs` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs) | +| `Microsoft.EventHub/namespaces/eventhubs/authorizationRules` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs/authorizationRules) | +| `Microsoft.EventHub/namespaces/eventhubs/consumergroups` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs/consumergroups) | +| `Microsoft.EventHub/namespaces/networkRuleSets` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/networkRuleSets) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/privateEndpoints` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/privateEndpoints/privateDnsZoneGroups) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/event-hub/namespace:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using encryption with Customer-Managed-Key](#example-2-using-encryption-with-customer-managed-key) +- [Using large parameter set](#example-3-using-large-parameter-set) +- [WAF-aligned](#example-4-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +
+ +via Bicep module + +```bicep +module namespace 'br/public:avm/res/event-hub/namespace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-ehnmin' + params: { + // Required parameters + name: 'ehnmin001' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "ehnmin001" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 2: _Using encryption with Customer-Managed-Key_ + +This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret. + + +

+ +via Bicep module + +```bicep +module namespace 'br/public:avm/res/event-hub/namespace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-ehnenc' + params: { + // Required parameters + name: 'ehnenc001' + // Non-required parameters + customerManagedKey: { + keyName: '' + keyVaultResourceId: '' + userAssignedIdentityResourceId: '' + } + location: '' + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [ + '' + ] + } + publicNetworkAccess: 'SecuredByPerimeter' + requireInfrastructureEncryption: true + skuName: 'Premium' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "ehnenc001" + }, + // Non-required parameters + "customerManagedKey": { + "value": { + "keyName": "", + "keyVaultResourceId": "", + "userAssignedIdentityResourceId": "" + } + }, + "location": { + "value": "" + }, + "managedIdentities": { + "value": { + "systemAssigned": false, + "userAssignedResourceIds": [ + "" + ] + } + }, + "publicNetworkAccess": { + "value": "SecuredByPerimeter" + }, + "requireInfrastructureEncryption": { + "value": true + }, + "skuName": { + "value": "Premium" + } + } +} +``` + +
+

+ +### Example 3: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

+ +via Bicep module + +```bicep +module namespace 'br/public:avm/res/event-hub/namespace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-ehnmax' + params: { + // Required parameters + name: 'ehnmax001' + // Non-required parameters + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + disableLocalAuth: true + eventhubs: [ + { + name: 'az-evh-x-001' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + } + { + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: 'eventhub' + captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: '' + captureDescriptionEnabled: true + captureDescriptionEncoding: 'Avro' + captureDescriptionIntervalInSeconds: 300 + captureDescriptionSizeLimitInBytes: 314572800 + captureDescriptionSkipEmptyArchives: true + consumergroups: [ + { + name: 'custom' + userMetadata: 'customMetadata' + } + ] + messageRetentionInDays: 1 + name: 'az-evh-x-002' + partitionCount: 2 + retentionDescriptionCleanupPolicy: 'Delete' + retentionDescriptionRetentionTimeInHours: 3 + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Reader' + } + ] + status: 'Active' + } + { + name: 'az-evh-x-003' + retentionDescriptionCleanupPolicy: 'Compact' + retentionDescriptionTombstoneRetentionTimeInHours: 24 + } + ] + isAutoInflateEnabled: true + kafkaEnabled: true + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + '' + ] + } + maximumThroughputUnits: 4 + minimumTlsVersion: '1.2' + networkRuleSets: { + defaultAction: 'Deny' + ipRules: [ + { + action: 'Allow' + ipMask: '10.10.10.10' + } + ] + publicNetworkAccess: 'Disabled' + trustedServiceAccessEnabled: false + virtualNetworkRules: [ + { + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: '' + } + ] + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + service: 'namespace' + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + publicNetworkAccess: 'Disabled' + roleAssignments: [ + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'Owner' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + } + { + principalId: '' + principalType: 'ServicePrincipal' + roleDefinitionIdOrName: '' + } + ] + skuCapacity: 2 + skuName: 'Standard' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + zoneRedundant: true + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "ehnmax001" + }, + // Non-required parameters + "authorizationRules": { + "value": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + }, + { + "name": "SendListenAccess", + "rights": [ + "Listen", + "Send" + ] + } + ] + }, + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "disableLocalAuth": { + "value": true + }, + "eventhubs": { + "value": [ + { + "name": "az-evh-x-001", + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ] + }, + { + "authorizationRules": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + }, + { + "name": "SendListenAccess", + "rights": [ + "Listen", + "Send" + ] + } + ], + "captureDescriptionDestinationArchiveNameFormat": "{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}", + "captureDescriptionDestinationBlobContainer": "eventhub", + "captureDescriptionDestinationName": "EventHubArchive.AzureBlockBlob", + "captureDescriptionDestinationStorageAccountResourceId": "", + "captureDescriptionEnabled": true, + "captureDescriptionEncoding": "Avro", + "captureDescriptionIntervalInSeconds": 300, + "captureDescriptionSizeLimitInBytes": 314572800, + "captureDescriptionSkipEmptyArchives": true, + "consumergroups": [ + { + "name": "custom", + "userMetadata": "customMetadata" + } + ], + "messageRetentionInDays": 1, + "name": "az-evh-x-002", + "partitionCount": 2, + "retentionDescriptionCleanupPolicy": "Delete", + "retentionDescriptionRetentionTimeInHours": 3, + "roleAssignments": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Reader" + } + ], + "status": "Active" + }, + { + "name": "az-evh-x-003", + "retentionDescriptionCleanupPolicy": "Compact", + "retentionDescriptionTombstoneRetentionTimeInHours": 24 + } + ] + }, + "isAutoInflateEnabled": { + "value": true + }, + "kafkaEnabled": { + "value": true + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "managedIdentities": { + "value": { + "systemAssigned": true, + "userAssignedResourceIds": [ + "" + ] + } + }, + "maximumThroughputUnits": { + "value": 4 + }, + "minimumTlsVersion": { + "value": "1.2" + }, + "networkRuleSets": { + "value": { + "defaultAction": "Deny", + "ipRules": [ + { + "action": "Allow", + "ipMask": "10.10.10.10" + } + ], + "publicNetworkAccess": "Disabled", + "trustedServiceAccessEnabled": false, + "virtualNetworkRules": [ + { + "ignoreMissingVnetServiceEndpoint": true, + "subnetResourceId": "" + } + ] + } + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "service": "namespace", + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "publicNetworkAccess": { + "value": "Disabled" + }, + "roleAssignments": { + "value": [ + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "Owner" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "b24988ac-6180-42a0-ab88-20f7382dd24c" + }, + { + "principalId": "", + "principalType": "ServicePrincipal", + "roleDefinitionIdOrName": "" + } + ] + }, + "skuCapacity": { + "value": 2 + }, + "skuName": { + "value": "Standard" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "zoneRedundant": { + "value": true + } + } +} +``` + +
+

+ +### Example 4: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

+ +via Bicep module + +```bicep +module namespace 'br/public:avm/res/event-hub/namespace:' = { + name: '${uniqueString(deployment().name, resourceLocation)}-test-ehnwaf' + params: { + // Required parameters + name: 'ehnwaf001' + // Non-required parameters + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + diagnosticSettings: [ + { + eventHubAuthorizationRuleResourceId: '' + eventHubName: '' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + name: 'customSetting' + storageAccountResourceId: '' + workspaceResourceId: '' + } + ] + disableLocalAuth: true + eventhubs: [ + { + name: 'az-evh-x-001' + } + { + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: 'eventhub' + captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: '' + captureDescriptionEnabled: true + captureDescriptionEncoding: 'Avro' + captureDescriptionIntervalInSeconds: 300 + captureDescriptionSizeLimitInBytes: 314572800 + captureDescriptionSkipEmptyArchives: true + consumergroups: [ + { + name: 'custom' + userMetadata: 'customMetadata' + } + ] + messageRetentionInDays: 1 + name: 'az-evh-x-002' + partitionCount: 2 + retentionDescriptionCleanupPolicy: 'Delete' + retentionDescriptionRetentionTimeInHours: 3 + status: 'Active' + } + { + name: 'az-evh-x-003' + retentionDescriptionCleanupPolicy: 'Compact' + retentionDescriptionTombstoneRetentionTimeInHours: 24 + } + ] + isAutoInflateEnabled: true + kafkaEnabled: true + location: '' + maximumThroughputUnits: 4 + minimumTlsVersion: '1.2' + networkRuleSets: { + defaultAction: 'Deny' + ipRules: [ + { + action: 'Allow' + ipMask: '10.10.10.10' + } + ] + trustedServiceAccessEnabled: false + virtualNetworkRules: [ + { + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: '' + } + ] + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + '' + ] + subnetResourceId: '' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } + ] + publicNetworkAccess: 'Disabled' + skuCapacity: 2 + skuName: 'Standard' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + zoneRedundant: true + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "ehnwaf001" + }, + // Non-required parameters + "authorizationRules": { + "value": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + }, + { + "name": "SendListenAccess", + "rights": [ + "Listen", + "Send" + ] + } + ] + }, + "diagnosticSettings": { + "value": [ + { + "eventHubAuthorizationRuleResourceId": "", + "eventHubName": "", + "metricCategories": [ + { + "category": "AllMetrics" + } + ], + "name": "customSetting", + "storageAccountResourceId": "", + "workspaceResourceId": "" + } + ] + }, + "disableLocalAuth": { + "value": true + }, + "eventhubs": { + "value": [ + { + "name": "az-evh-x-001" + }, + { + "authorizationRules": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + }, + { + "name": "SendListenAccess", + "rights": [ + "Listen", + "Send" + ] + } + ], + "captureDescriptionDestinationArchiveNameFormat": "{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}", + "captureDescriptionDestinationBlobContainer": "eventhub", + "captureDescriptionDestinationName": "EventHubArchive.AzureBlockBlob", + "captureDescriptionDestinationStorageAccountResourceId": "", + "captureDescriptionEnabled": true, + "captureDescriptionEncoding": "Avro", + "captureDescriptionIntervalInSeconds": 300, + "captureDescriptionSizeLimitInBytes": 314572800, + "captureDescriptionSkipEmptyArchives": true, + "consumergroups": [ + { + "name": "custom", + "userMetadata": "customMetadata" + } + ], + "messageRetentionInDays": 1, + "name": "az-evh-x-002", + "partitionCount": 2, + "retentionDescriptionCleanupPolicy": "Delete", + "retentionDescriptionRetentionTimeInHours": 3, + "status": "Active" + }, + { + "name": "az-evh-x-003", + "retentionDescriptionCleanupPolicy": "Compact", + "retentionDescriptionTombstoneRetentionTimeInHours": 24 + } + ] + }, + "isAutoInflateEnabled": { + "value": true + }, + "kafkaEnabled": { + "value": true + }, + "location": { + "value": "" + }, + "maximumThroughputUnits": { + "value": 4 + }, + "minimumTlsVersion": { + "value": "1.2" + }, + "networkRuleSets": { + "value": { + "defaultAction": "Deny", + "ipRules": [ + { + "action": "Allow", + "ipMask": "10.10.10.10" + } + ], + "trustedServiceAccessEnabled": false, + "virtualNetworkRules": [ + { + "ignoreMissingVnetServiceEndpoint": true, + "subnetResourceId": "" + } + ] + } + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneResourceIds": [ + "" + ], + "subnetResourceId": "", + "tags": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + ] + }, + "publicNetworkAccess": { + "value": "Disabled" + }, + "skuCapacity": { + "value": 2 + }, + "skuName": { + "value": "Standard" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "zoneRedundant": { + "value": true + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the event hub namespace. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`authorizationRules`](#parameter-authorizationrules) | array | Authorization Rules for the Event Hub namespace. | +| [`customerManagedKey`](#parameter-customermanagedkey) | object | The customer managed key definition. | +| [`diagnosticSettings`](#parameter-diagnosticsettings) | array | The diagnostic settings of the service. | +| [`disableLocalAuth`](#parameter-disablelocalauth) | bool | This property disables SAS authentication for the Event Hubs namespace. | +| [`disasterRecoveryConfig`](#parameter-disasterrecoveryconfig) | object | The disaster recovery config for this namespace. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`eventhubs`](#parameter-eventhubs) | array | The event hubs to deploy into this namespace. | +| [`isAutoInflateEnabled`](#parameter-isautoinflateenabled) | bool | Switch to enable the Auto Inflate feature of Event Hub. Auto Inflate is not supported in Premium SKU EventHub. | +| [`kafkaEnabled`](#parameter-kafkaenabled) | bool | Value that indicates whether Kafka is enabled for Event Hubs Namespace. | +| [`location`](#parameter-location) | string | Location for all resources. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`managedIdentities`](#parameter-managedidentities) | object | The managed identity definition for this resource. | +| [`maximumThroughputUnits`](#parameter-maximumthroughputunits) | int | Upper limit of throughput units when AutoInflate is enabled, value should be within 0 to 20 throughput units. | +| [`minimumTlsVersion`](#parameter-minimumtlsversion) | string | The minimum TLS version for the cluster to support. | +| [`networkRuleSets`](#parameter-networkrulesets) | object | Configure networking options. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace. | +| [`privateEndpoints`](#parameter-privateendpoints) | array | Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. | +| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set. | +| [`requireInfrastructureEncryption`](#parameter-requireinfrastructureencryption) | bool | Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`skuCapacity`](#parameter-skucapacity) | int | The Event Hub's throughput units for Basic or Standard tiers, where value should be 0 to 20 throughput units. The Event Hubs premium units for Premium tier, where value should be 0 to 10 premium units. | +| [`skuName`](#parameter-skuname) | string | event hub plan SKU name. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`zoneRedundant`](#parameter-zoneredundant) | bool | Switch to make the Event Hub Namespace zone redundant. | + +### Parameter: `name` + +The name of the event hub namespace. + +- Required: Yes +- Type: string + +### Parameter: `authorizationRules` + +Authorization Rules for the Event Hub namespace. + +- Required: No +- Type: array +- Default: + ```Bicep + [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + ] + ``` + +### Parameter: `customerManagedKey` + +The customer managed key definition. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyName`](#parameter-customermanagedkeykeyname) | string | The name of the customer managed key to use for encryption. | +| [`keyVaultResourceId`](#parameter-customermanagedkeykeyvaultresourceid) | string | The resource ID of a key vault to reference a customer managed key for encryption from. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`keyVersion`](#parameter-customermanagedkeykeyversion) | string | The version of the customer managed key to reference for encryption. If not provided, using 'latest'. | +| [`userAssignedIdentityResourceId`](#parameter-customermanagedkeyuserassignedidentityresourceid) | string | User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. | + +### Parameter: `customerManagedKey.keyName` + +The name of the customer managed key to use for encryption. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVaultResourceId` + +The resource ID of a key vault to reference a customer managed key for encryption from. + +- Required: Yes +- Type: string + +### Parameter: `customerManagedKey.keyVersion` + +The version of the customer managed key to reference for encryption. If not provided, using 'latest'. + +- Required: No +- Type: string + +### Parameter: `customerManagedKey.userAssignedIdentityResourceId` + +User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings` + +The diagnostic settings of the service. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubAuthorizationRuleResourceId`](#parameter-diagnosticsettingseventhubauthorizationruleresourceid) | string | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| [`eventHubName`](#parameter-diagnosticsettingseventhubname) | string | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`logAnalyticsDestinationType`](#parameter-diagnosticsettingsloganalyticsdestinationtype) | string | A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. | +| [`logCategoriesAndGroups`](#parameter-diagnosticsettingslogcategoriesandgroups) | array | The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. | +| [`marketplacePartnerResourceId`](#parameter-diagnosticsettingsmarketplacepartnerresourceid) | string | The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. | +| [`metricCategories`](#parameter-diagnosticsettingsmetriccategories) | array | The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. | +| [`name`](#parameter-diagnosticsettingsname) | string | The name of diagnostic setting. | +| [`storageAccountResourceId`](#parameter-diagnosticsettingsstorageaccountresourceid) | string | Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | +| [`workspaceResourceId`](#parameter-diagnosticsettingsworkspaceresourceid) | string | Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. | + +### Parameter: `diagnosticSettings.eventHubAuthorizationRuleResourceId` + +Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.eventHubName` + +Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logAnalyticsDestinationType` + +A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'AzureDiagnostics' + 'Dedicated' + ] + ``` + +### Parameter: `diagnosticSettings.logCategoriesAndGroups` + +The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection. + +- Required: No +- Type: array + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingslogcategoriesandgroupscategory) | string | Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. | +| [`categoryGroup`](#parameter-diagnosticsettingslogcategoriesandgroupscategorygroup) | string | Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. | +| [`enabled`](#parameter-diagnosticsettingslogcategoriesandgroupsenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.category` + +Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.categoryGroup` + +Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.logCategoriesAndGroups.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `diagnosticSettings.marketplacePartnerResourceId` + +The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.metricCategories` + +The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`category`](#parameter-diagnosticsettingsmetriccategoriescategory) | string | Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`enabled`](#parameter-diagnosticsettingsmetriccategoriesenabled) | bool | Enable or disable the category explicitly. Default is `true`. | + +### Parameter: `diagnosticSettings.metricCategories.category` + +Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics. + +- Required: Yes +- Type: string + +### Parameter: `diagnosticSettings.metricCategories.enabled` + +Enable or disable the category explicitly. Default is `true`. + +- Required: No +- Type: bool + +### Parameter: `diagnosticSettings.name` + +The name of diagnostic setting. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.storageAccountResourceId` + +Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `diagnosticSettings.workspaceResourceId` + +Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub. + +- Required: No +- Type: string + +### Parameter: `disableLocalAuth` + +This property disables SAS authentication for the Event Hubs namespace. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `disasterRecoveryConfig` + +The disaster recovery config for this namespace. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `eventhubs` + +The event hubs to deploy into this namespace. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `isAutoInflateEnabled` + +Switch to enable the Auto Inflate feature of Event Hub. Auto Inflate is not supported in Premium SKU EventHub. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `kafkaEnabled` + +Value that indicates whether Kafka is enabled for Event Hubs Namespace. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `location` + +Location for all resources. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `managedIdentities` + +The managed identity definition for this resource. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`systemAssigned`](#parameter-managedidentitiessystemassigned) | bool | Enables system assigned managed identity on the resource. | +| [`userAssignedResourceIds`](#parameter-managedidentitiesuserassignedresourceids) | array | The resource ID(s) to assign to the resource. | + +### Parameter: `managedIdentities.systemAssigned` + +Enables system assigned managed identity on the resource. + +- Required: No +- Type: bool + +### Parameter: `managedIdentities.userAssignedResourceIds` + +The resource ID(s) to assign to the resource. + +- Required: No +- Type: array + +### Parameter: `maximumThroughputUnits` + +Upper limit of throughput units when AutoInflate is enabled, value should be within 0 to 20 throughput units. + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `minimumTlsVersion` + +The minimum TLS version for the cluster to support. + +- Required: No +- Type: string +- Default: `'1.2'` +- Allowed: + ```Bicep + [ + '1.0' + '1.1' + '1.2' + ] + ``` + +### Parameter: `networkRuleSets` + +Configure networking options. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `privateEndpoints` + +Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | +| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`enableTelemetry`](#parameter-privateendpointsenabletelemetry) | bool | Enable/Disable usage telemetry for module. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | +| [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | +| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`lock`](#parameter-privateendpointslock) | object | Specify the type of lock. | +| [`manualConnectionRequestMessage`](#parameter-privateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | +| [`name`](#parameter-privateendpointsname) | string | The name of the private endpoint. | +| [`privateDnsZoneGroupName`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | + +### Parameter: `privateEndpoints.subnetResourceId` + +Resource ID of the subnet where the endpoint needs to be created. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` + +Application security groups in which the private endpoint IP configuration is included. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.customDnsConfigs` + +Custom DNS configurations. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`fqdn`](#parameter-privateendpointscustomdnsconfigsfqdn) | string | Fqdn that resolves to private endpoint IP address. | +| [`ipAddresses`](#parameter-privateendpointscustomdnsconfigsipaddresses) | array | A list of private IP addresses of the private endpoint. | + +### Parameter: `privateEndpoints.customDnsConfigs.fqdn` + +Fqdn that resolves to private endpoint IP address. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.customDnsConfigs.ipAddresses` + +A list of private IP addresses of the private endpoint. + +- Required: Yes +- Type: array + +### Parameter: `privateEndpoints.customNetworkInterfaceName` + +The custom name of the network interface attached to the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.enableTelemetry` + +Enable/Disable usage telemetry for module. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.ipConfigurations` + +A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsipconfigurationsname) | string | The name of the resource that is unique within a resource group. | +| [`properties`](#parameter-privateendpointsipconfigurationsproperties) | object | Properties of private endpoint IP configurations. | + +### Parameter: `privateEndpoints.ipConfigurations.name` + +The name of the resource that is unique within a resource group. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties` + +Properties of private endpoint IP configurations. + +- Required: Yes +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`groupId`](#parameter-privateendpointsipconfigurationspropertiesgroupid) | string | The ID of a group obtained from the remote resource that this private endpoint should connect to. | +| [`memberName`](#parameter-privateendpointsipconfigurationspropertiesmembername) | string | The member name of a group obtained from the remote resource that this private endpoint should connect to. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | + +### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` + +The ID of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.memberName` + +The member name of a group obtained from the remote resource that this private endpoint should connect to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` + +A private IP address obtained from the private endpoint's subnet. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.isManualConnection` + +If Manual Private Link Connection is required. + +- Required: No +- Type: bool + +### Parameter: `privateEndpoints.location` + +The location to deploy the private endpoint to. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.lock` + +Specify the type of lock. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-privateendpointslockkind) | string | Specify the type of lock. | +| [`name`](#parameter-privateendpointslockname) | string | Specify the name of lock. | + +### Parameter: `privateEndpoints.lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `privateEndpoints.lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.manualConnectionRequestMessage` + +A message passed to the owner of the remote resource with the manual connection request. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.name` + +The name of the private endpoint. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroupName` + +The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. + +- Required: No +- Type: array + +### Parameter: `privateEndpoints.roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-privateendpointsroleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-privateendpointsroleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-privateendpointsroleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-privateendpointsroleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-privateendpointsroleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-privateendpointsroleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-privateendpointsroleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `privateEndpoints.roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `privateEndpoints.roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `privateEndpoints.service` + +The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.tags` + +Tags to be applied on all resources/resource groups in this deployment. + +- Required: No +- Type: object + +### Parameter: `publicNetworkAccess` + +Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'Disabled' + 'Enabled' + 'SecuredByPerimeter' + ] + ``` + +### Parameter: `requireInfrastructureEncryption` + +Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `skuCapacity` + +The Event Hub's throughput units for Basic or Standard tiers, where value should be 0 to 20 throughput units. The Event Hubs premium units for Premium tier, where value should be 0 to 10 premium units. + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `skuName` + +event hub plan SKU name. + +- Required: No +- Type: string +- Default: `'Standard'` +- Allowed: + ```Bicep + [ + 'Basic' + 'Premium' + 'Standard' + ] + ``` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `zoneRedundant` + +Switch to make the Event Hub Namespace zone redundant. + +- Required: No +- Type: bool +- Default: `False` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the eventspace. | +| `resourceGroupName` | string | The resource group where the namespace is deployed. | +| `resourceId` | string | The resource ID of the eventspace. | +| `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | + +## Cross-referenced modules + +This section gives you an overview of all local-referenced module files (i.e., other CARML modules that are referenced in this module) and all remote-referenced files (i.e., Bicep modules that are referenced from a Bicep Registry or Template Specs). + +| Reference | Type | +| :-- | :-- | +| `br/public:avm/res/network/private-endpoint:0.4.0` | Remote reference | + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/authorization-rule/README.md b/avm/res/event-hub/namespace/authorization-rule/README.md new file mode 100644 index 0000000000..d5c760abe8 --- /dev/null +++ b/avm/res/event-hub/namespace/authorization-rule/README.md @@ -0,0 +1,84 @@ +# Event Hub Namespace Authorization Rule `[Microsoft.EventHub/namespaces/authorizationRules]` + +This module deploys an Event Hub Namespace Authorization Rule. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.EventHub/namespaces/authorizationRules` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/authorizationRules) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the authorization rule. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`namespaceName`](#parameter-namespacename) | string | The name of the parent event hub namespace. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`rights`](#parameter-rights) | array | The rights associated with the rule. | + +### Parameter: `name` + +The name of the authorization rule. + +- Required: Yes +- Type: string + +### Parameter: `namespaceName` + +The name of the parent event hub namespace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `rights` + +The rights associated with the rule. + +- Required: No +- Type: array +- Default: `[]` +- Allowed: + ```Bicep + [ + 'Listen' + 'Manage' + 'Send' + ] + ``` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the authorization rule. | +| `resourceGroupName` | string | The name of the resource group the authorization rule was created in. | +| `resourceId` | string | The resource ID of the authorization rule. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/authorization-rule/main.bicep b/avm/res/event-hub/namespace/authorization-rule/main.bicep new file mode 100644 index 0000000000..413097a62e --- /dev/null +++ b/avm/res/event-hub/namespace/authorization-rule/main.bicep @@ -0,0 +1,38 @@ +metadata name = 'Event Hub Namespace Authorization Rule' +metadata description = 'This module deploys an Event Hub Namespace Authorization Rule.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.') +param namespaceName string + +@description('Required. The name of the authorization rule.') +param name string + +@description('Optional. The rights associated with the rule.') +@allowed([ + 'Listen' + 'Manage' + 'Send' +]) +param rights array = [] + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource authorizationRule 'Microsoft.EventHub/namespaces/authorizationRules@2022-10-01-preview' = { + name: name + parent: namespace + properties: { + rights: rights + } +} + +@description('The name of the authorization rule.') +output name string = authorizationRule.name + +@description('The resource ID of the authorization rule.') +output resourceId string = authorizationRule.id + +@description('The name of the resource group the authorization rule was created in.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/event-hub/namespace/authorization-rule/main.json b/avm/res/event-hub/namespace/authorization-rule/main.json new file mode 100644 index 0000000000..6516efc5ac --- /dev/null +++ b/avm/res/event-hub/namespace/authorization-rule/main.json @@ -0,0 +1,73 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10638309014943371587" + }, + "name": "Event Hub Namespace Authorization Rule", + "description": "This module deploys an Event Hub Namespace Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the authorization rule." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/authorizationRules', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/disaster-recovery-config/README.md b/avm/res/event-hub/namespace/disaster-recovery-config/README.md new file mode 100644 index 0000000000..71781f809f --- /dev/null +++ b/avm/res/event-hub/namespace/disaster-recovery-config/README.md @@ -0,0 +1,76 @@ +# Event Hub Namespace Disaster Recovery Configs `[Microsoft.EventHub/namespaces/disasterRecoveryConfigs]` + +This module deploys an Event Hub Namespace Disaster Recovery Config. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.EventHub/namespaces/disasterRecoveryConfigs` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/disasterRecoveryConfigs) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the disaster recovery config. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`namespaceName`](#parameter-namespacename) | string | The name of the parent event hub namespace. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`partnerNamespaceId`](#parameter-partnernamespaceid) | string | Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing. | + +### Parameter: `name` + +The name of the disaster recovery config. + +- Required: Yes +- Type: string + +### Parameter: `namespaceName` + +The name of the parent event hub namespace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `partnerNamespaceId` + +Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing. + +- Required: No +- Type: string +- Default: `''` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the disaster recovery config. | +| `resourceGroupName` | string | The name of the resource group the disaster recovery config was created in. | +| `resourceId` | string | The resource ID of the disaster recovery config. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/disaster-recovery-config/main.bicep b/avm/res/event-hub/namespace/disaster-recovery-config/main.bicep new file mode 100644 index 0000000000..cd99f99b75 --- /dev/null +++ b/avm/res/event-hub/namespace/disaster-recovery-config/main.bicep @@ -0,0 +1,33 @@ +metadata name = 'Event Hub Namespace Disaster Recovery Configs' +metadata description = 'This module deploys an Event Hub Namespace Disaster Recovery Config.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.') +param namespaceName string + +@description('Required. The name of the disaster recovery config.') +param name string + +@description('Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing.') +param partnerNamespaceId string = '' + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource disasterRecoveryConfig 'Microsoft.EventHub/namespaces/disasterRecoveryConfigs@2022-10-01-preview' = { + name: name + parent: namespace + properties: { + partnerNamespace: partnerNamespaceId + } +} + +@description('The name of the disaster recovery config.') +output name string = disasterRecoveryConfig.name + +@description('The resource ID of the disaster recovery config.') +output resourceId string = disasterRecoveryConfig.id + +@description('The name of the resource group the disaster recovery config was created in.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/event-hub/namespace/disaster-recovery-config/main.json b/avm/res/event-hub/namespace/disaster-recovery-config/main.json new file mode 100644 index 0000000000..5e57cbee56 --- /dev/null +++ b/avm/res/event-hub/namespace/disaster-recovery-config/main.json @@ -0,0 +1,68 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14933577565840576961" + }, + "name": "Event Hub Namespace Disaster Recovery Configs", + "description": "This module deploys an Event Hub Namespace Disaster Recovery Config.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the disaster recovery config." + } + }, + "partnerNamespaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/disasterRecoveryConfigs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "partnerNamespace": "[parameters('partnerNamespaceId')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the disaster recovery config." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the disaster recovery config." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/disasterRecoveryConfigs', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the disaster recovery config was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/eventhub/README.md b/avm/res/event-hub/namespace/eventhub/README.md new file mode 100644 index 0000000000..b83ef1786c --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/README.md @@ -0,0 +1,398 @@ +# Event Hub Namespace Event Hubs `[Microsoft.EventHub/namespaces/eventhubs]` + +This module deploys an Event Hub Namespace Event Hub. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | +| `Microsoft.EventHub/namespaces/eventhubs` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs) | +| `Microsoft.EventHub/namespaces/eventhubs/authorizationRules` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs/authorizationRules) | +| `Microsoft.EventHub/namespaces/eventhubs/consumergroups` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs/consumergroups) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the event hub. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`namespaceName`](#parameter-namespacename) | string | The name of the parent event hub namespace. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`authorizationRules`](#parameter-authorizationrules) | array | Authorization Rules for the event hub. | +| [`captureDescriptionDestinationArchiveNameFormat`](#parameter-capturedescriptiondestinationarchivenameformat) | string | Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}. Here all the parameters (Namespace,EventHub .. etc) are mandatory irrespective of order. | +| [`captureDescriptionDestinationBlobContainer`](#parameter-capturedescriptiondestinationblobcontainer) | string | Blob container Name. | +| [`captureDescriptionDestinationName`](#parameter-capturedescriptiondestinationname) | string | Name for capture destination. | +| [`captureDescriptionDestinationStorageAccountResourceId`](#parameter-capturedescriptiondestinationstorageaccountresourceid) | string | Resource ID of the storage account to be used to create the blobs. | +| [`captureDescriptionEnabled`](#parameter-capturedescriptionenabled) | bool | A value that indicates whether capture description is enabled. | +| [`captureDescriptionEncoding`](#parameter-capturedescriptionencoding) | string | Enumerates the possible values for the encoding format of capture description. Note: "AvroDeflate" will be deprecated in New API Version. | +| [`captureDescriptionIntervalInSeconds`](#parameter-capturedescriptionintervalinseconds) | int | The time window allows you to set the frequency with which the capture to Azure Blobs will happen. | +| [`captureDescriptionSizeLimitInBytes`](#parameter-capturedescriptionsizelimitinbytes) | int | The size window defines the amount of data built up in your Event Hub before an capture operation. | +| [`captureDescriptionSkipEmptyArchives`](#parameter-capturedescriptionskipemptyarchives) | bool | A value that indicates whether to Skip Empty Archives. | +| [`consumergroups`](#parameter-consumergroups) | array | The consumer groups to create in this event hub instance. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`messageRetentionInDays`](#parameter-messageretentionindays) | int | Number of days to retain the events for this Event Hub, value should be 1 to 7 days. Will be automatically set to infinite retention if cleanup policy is set to "Compact". | +| [`partitionCount`](#parameter-partitioncount) | int | Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions. | +| [`retentionDescriptionCleanupPolicy`](#parameter-retentiondescriptioncleanuppolicy) | string | Retention cleanup policy. Enumerates the possible values for cleanup policy. | +| [`retentionDescriptionRetentionTimeInHours`](#parameter-retentiondescriptionretentiontimeinhours) | int | Retention time in hours. Number of hours to retain the events for this Event Hub. This value is only used when cleanupPolicy is Delete. If cleanupPolicy is Compact the returned value of this property is Long.MaxValue. | +| [`retentionDescriptionTombstoneRetentionTimeInHours`](#parameter-retentiondescriptiontombstoneretentiontimeinhours) | int | Retention cleanup policy. Number of hours to retain the tombstone markers of a compacted Event Hub. This value is only used when cleanupPolicy is Compact. Consumer must complete reading the tombstone marker within this specified amount of time if consumer begins from starting offset to ensure they get a valid snapshot for the specific key described by the tombstone marker within the compacted Event Hub. | +| [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignments to create. | +| [`status`](#parameter-status) | string | Enumerates the possible values for the status of the Event Hub. | + +### Parameter: `name` + +The name of the event hub. + +- Required: Yes +- Type: string + +### Parameter: `namespaceName` + +The name of the parent event hub namespace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `authorizationRules` + +Authorization Rules for the event hub. + +- Required: No +- Type: array +- Default: + ```Bicep + [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + ] + ``` + +### Parameter: `captureDescriptionDestinationArchiveNameFormat` + +Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}. Here all the parameters (Namespace,EventHub .. etc) are mandatory irrespective of order. + +- Required: No +- Type: string +- Default: `'{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}'` + +### Parameter: `captureDescriptionDestinationBlobContainer` + +Blob container Name. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `captureDescriptionDestinationName` + +Name for capture destination. + +- Required: No +- Type: string +- Default: `'EventHubArchive.AzureBlockBlob'` + +### Parameter: `captureDescriptionDestinationStorageAccountResourceId` + +Resource ID of the storage account to be used to create the blobs. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `captureDescriptionEnabled` + +A value that indicates whether capture description is enabled. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `captureDescriptionEncoding` + +Enumerates the possible values for the encoding format of capture description. Note: "AvroDeflate" will be deprecated in New API Version. + +- Required: No +- Type: string +- Default: `'Avro'` +- Allowed: + ```Bicep + [ + 'Avro' + 'AvroDeflate' + ] + ``` + +### Parameter: `captureDescriptionIntervalInSeconds` + +The time window allows you to set the frequency with which the capture to Azure Blobs will happen. + +- Required: No +- Type: int +- Default: `300` + +### Parameter: `captureDescriptionSizeLimitInBytes` + +The size window defines the amount of data built up in your Event Hub before an capture operation. + +- Required: No +- Type: int +- Default: `314572800` + +### Parameter: `captureDescriptionSkipEmptyArchives` + +A value that indicates whether to Skip Empty Archives. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `consumergroups` + +The consumer groups to create in this event hub instance. + +- Required: No +- Type: array +- Default: + ```Bicep + [ + { + name: '$Default' + } + ] + ``` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `messageRetentionInDays` + +Number of days to retain the events for this Event Hub, value should be 1 to 7 days. Will be automatically set to infinite retention if cleanup policy is set to "Compact". + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `partitionCount` + +Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions. + +- Required: No +- Type: int +- Default: `2` + +### Parameter: `retentionDescriptionCleanupPolicy` + +Retention cleanup policy. Enumerates the possible values for cleanup policy. + +- Required: No +- Type: string +- Default: `'Delete'` +- Allowed: + ```Bicep + [ + 'Compact' + 'Delete' + ] + ``` + +### Parameter: `retentionDescriptionRetentionTimeInHours` + +Retention time in hours. Number of hours to retain the events for this Event Hub. This value is only used when cleanupPolicy is Delete. If cleanupPolicy is Compact the returned value of this property is Long.MaxValue. + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `retentionDescriptionTombstoneRetentionTimeInHours` + +Retention cleanup policy. Number of hours to retain the tombstone markers of a compacted Event Hub. This value is only used when cleanupPolicy is Compact. Consumer must complete reading the tombstone marker within this specified amount of time if consumer begins from starting offset to ensure they get a valid snapshot for the specific key described by the tombstone marker within the compacted Event Hub. + +- Required: No +- Type: int +- Default: `1` + +### Parameter: `roleAssignments` + +Array of role assignments to create. + +- Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`principalId`](#parameter-roleassignmentsprincipalid) | string | The principal ID of the principal (user/group/identity) to assign the role to. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | string | The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`condition`](#parameter-roleassignmentscondition) | string | The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". | +| [`conditionVersion`](#parameter-roleassignmentsconditionversion) | string | Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | string | The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | string | The description of the role assignment. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | string | The principal type of the assigned principal ID. | + +### Parameter: `roleAssignments.principalId` + +The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.condition` + +The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container". + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Version of the condition. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + '2.0' + ] + ``` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalType` + +The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'Device' + 'ForeignGroup' + 'Group' + 'ServicePrincipal' + 'User' + ] + ``` + +### Parameter: `status` + +Enumerates the possible values for the status of the Event Hub. + +- Required: No +- Type: string +- Default: `'Active'` +- Allowed: + ```Bicep + [ + 'Active' + 'Creating' + 'Deleting' + 'Disabled' + 'ReceiveDisabled' + 'Renaming' + 'Restoring' + 'SendDisabled' + 'Unknown' + ] + ``` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the event hub. | +| `resourceGroupName` | string | The resource group the event hub was deployed into. | +| `resourceId` | string | The resource ID of the event hub. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/eventhub/authorization-rule/README.md b/avm/res/event-hub/namespace/eventhub/authorization-rule/README.md new file mode 100644 index 0000000000..5076e02550 --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/authorization-rule/README.md @@ -0,0 +1,92 @@ +# Event Hub Namespace Event Hub Authorization Rules `[Microsoft.EventHub/namespaces/eventhubs/authorizationRules]` + +This module deploys an Event Hub Namespace Event Hub Authorization Rule. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.EventHub/namespaces/eventhubs/authorizationRules` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs/authorizationRules) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the authorization rule. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubName`](#parameter-eventhubname) | string | The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment. | +| [`namespaceName`](#parameter-namespacename) | string | The name of the parent event hub namespace. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`rights`](#parameter-rights) | array | The rights associated with the rule. | + +### Parameter: `name` + +The name of the authorization rule. + +- Required: Yes +- Type: string + +### Parameter: `eventHubName` + +The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `namespaceName` + +The name of the parent event hub namespace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `rights` + +The rights associated with the rule. + +- Required: No +- Type: array +- Default: `[]` +- Allowed: + ```Bicep + [ + 'Listen' + 'Manage' + 'Send' + ] + ``` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the authorization rule. | +| `resourceGroupName` | string | The name of the resource group the authorization rule was created in. | +| `resourceId` | string | The resource ID of the authorization rule. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/eventhub/authorization-rule/main.bicep b/avm/res/event-hub/namespace/eventhub/authorization-rule/main.bicep new file mode 100644 index 0000000000..72cb544b36 --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/authorization-rule/main.bicep @@ -0,0 +1,45 @@ +metadata name = 'Event Hub Namespace Event Hub Authorization Rules' +metadata description = 'This module deploys an Event Hub Namespace Event Hub Authorization Rule.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.') +param namespaceName string + +@description('Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment.') +param eventHubName string + +@description('Required. The name of the authorization rule.') +param name string + +@description('Optional. The rights associated with the rule.') +@allowed([ + 'Listen' + 'Manage' + 'Send' +]) +param rights array = [] + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName + + resource eventhub 'eventhubs@2022-10-01-preview' existing = { + name: eventHubName + } +} + +resource authorizationRule 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules@2022-10-01-preview' = { + name: name + parent: namespace::eventhub + properties: { + rights: rights + } +} + +@description('The name of the authorization rule.') +output name string = authorizationRule.name + +@description('The resource ID of the authorization rule.') +output resourceId string = authorizationRule.id + +@description('The name of the resource group the authorization rule was created in.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json b/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json new file mode 100644 index 0000000000..9b5e8a5edc --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/authorization-rule/main.json @@ -0,0 +1,79 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "16757979367783376523" + }, + "name": "Event Hub Namespace Event Hub Authorization Rules", + "description": "This module deploys an Event Hub Namespace Event Hub Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the authorization rule." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs/authorizationRules', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/eventhub/consumergroup/README.md b/avm/res/event-hub/namespace/eventhub/consumergroup/README.md new file mode 100644 index 0000000000..3797dc609f --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/consumergroup/README.md @@ -0,0 +1,84 @@ +# Event Hub Namespace Event Hub Consumer Groups `[Microsoft.EventHub/namespaces/eventhubs/consumergroups]` + +This module deploys an Event Hub Namespace Event Hub Consumer Group. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.EventHub/namespaces/eventhubs/consumergroups` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/eventhubs/consumergroups) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the consumer group. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`eventHubName`](#parameter-eventhubname) | string | The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment. | +| [`namespaceName`](#parameter-namespacename) | string | The name of the parent event hub namespace. Required if the template is used in a standalone deployment.s. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`userMetadata`](#parameter-usermetadata) | string | User Metadata is a placeholder to store user-defined string data with maximum length 1024. e.g. it can be used to store descriptive data, such as list of teams and their contact information also user-defined configuration settings can be stored. | + +### Parameter: `name` + +The name of the consumer group. + +- Required: Yes +- Type: string + +### Parameter: `eventHubName` + +The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `namespaceName` + +The name of the parent event hub namespace. Required if the template is used in a standalone deployment.s. + +- Required: Yes +- Type: string + +### Parameter: `userMetadata` + +User Metadata is a placeholder to store user-defined string data with maximum length 1024. e.g. it can be used to store descriptive data, such as list of teams and their contact information also user-defined configuration settings can be stored. + +- Required: No +- Type: string +- Default: `''` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the consumer group. | +| `resourceGroupName` | string | The name of the resource group the consumer group was created in. | +| `resourceId` | string | The resource ID of the consumer group. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/eventhub/consumergroup/main.bicep b/avm/res/event-hub/namespace/eventhub/consumergroup/main.bicep new file mode 100644 index 0000000000..4718d278b0 --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/consumergroup/main.bicep @@ -0,0 +1,40 @@ +metadata name = 'Event Hub Namespace Event Hub Consumer Groups' +metadata description = 'This module deploys an Event Hub Namespace Event Hub Consumer Group.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.s.') +param namespaceName string + +@description('Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment.') +param eventHubName string + +@description('Required. The name of the consumer group.') +param name string + +@description('Optional. User Metadata is a placeholder to store user-defined string data with maximum length 1024. e.g. it can be used to store descriptive data, such as list of teams and their contact information also user-defined configuration settings can be stored.') +param userMetadata string = '' + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName + + resource eventhub 'eventhubs@2022-10-01-preview' existing = { + name: eventHubName + } +} + +resource consumerGroup 'Microsoft.EventHub/namespaces/eventhubs/consumergroups@2022-10-01-preview' = { + name: name + parent: namespace::eventhub + properties: { + userMetadata: !empty(userMetadata) ? userMetadata : null + } +} + +@description('The name of the consumer group.') +output name string = consumerGroup.name + +@description('The resource ID of the consumer group.') +output resourceId string = consumerGroup.id + +@description('The name of the resource group the consumer group was created in.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/event-hub/namespace/eventhub/consumergroup/main.json b/avm/res/event-hub/namespace/eventhub/consumergroup/main.json new file mode 100644 index 0000000000..cd74392666 --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/consumergroup/main.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "697710281814211564" + }, + "name": "Event Hub Namespace Event Hub Consumer Groups", + "description": "This module deploys an Event Hub Namespace Event Hub Consumer Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.s." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the consumer group." + } + }, + "userMetadata": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. User Metadata is a placeholder to store user-defined string data with maximum length 1024. e.g. it can be used to store descriptive data, such as list of teams and their contact information also user-defined configuration settings can be stored." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/eventhubs/consumergroups", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "userMetadata": "[if(not(empty(parameters('userMetadata'))), parameters('userMetadata'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the consumer group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the consumer group." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs/consumergroups', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the consumer group was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/eventhub/main.bicep b/avm/res/event-hub/namespace/eventhub/main.bicep new file mode 100644 index 0000000000..1cb2cbbf4d --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/main.bicep @@ -0,0 +1,247 @@ +metadata name = 'Event Hub Namespace Event Hubs' +metadata description = 'This module deploys an Event Hub Namespace Event Hub.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.') +param namespaceName string + +@description('Required. The name of the event hub.') +param name string + +@description('Optional. Authorization Rules for the event hub.') +param authorizationRules array = [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } +] + +@description('Optional. Number of days to retain the events for this Event Hub, value should be 1 to 7 days. Will be automatically set to infinite retention if cleanup policy is set to "Compact".') +@minValue(1) +@maxValue(7) +param messageRetentionInDays int = 1 + +@description('Optional. Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions.') +@minValue(1) +@maxValue(32) +param partitionCount int = 2 + +@description('Optional. Enumerates the possible values for the status of the Event Hub.') +@allowed([ + 'Active' + 'Creating' + 'Deleting' + 'Disabled' + 'ReceiveDisabled' + 'Renaming' + 'Restoring' + 'SendDisabled' + 'Unknown' +]) +param status string = 'Active' + +@description('Optional. The consumer groups to create in this event hub instance.') +param consumergroups array = [ + { + name: '$Default' + } +] + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Name for capture destination.') +param captureDescriptionDestinationName string = 'EventHubArchive.AzureBlockBlob' + +@description('Optional. Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}. Here all the parameters (Namespace,EventHub .. etc) are mandatory irrespective of order.') +param captureDescriptionDestinationArchiveNameFormat string = '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + +@description('Optional. Blob container Name.') +param captureDescriptionDestinationBlobContainer string = '' + +@description('Optional. Resource ID of the storage account to be used to create the blobs.') +param captureDescriptionDestinationStorageAccountResourceId string = '' + +@description('Optional. A value that indicates whether capture description is enabled.') +param captureDescriptionEnabled bool = false + +@description('Optional. Enumerates the possible values for the encoding format of capture description. Note: "AvroDeflate" will be deprecated in New API Version.') +@allowed([ + 'Avro' + 'AvroDeflate' +]) +param captureDescriptionEncoding string = 'Avro' + +@description('Optional. The time window allows you to set the frequency with which the capture to Azure Blobs will happen.') +@minValue(60) +@maxValue(900) +param captureDescriptionIntervalInSeconds int = 300 + +@description('Optional. The size window defines the amount of data built up in your Event Hub before an capture operation.') +@minValue(10485760) +@maxValue(524288000) +param captureDescriptionSizeLimitInBytes int = 314572800 + +@description('Optional. A value that indicates whether to Skip Empty Archives.') +param captureDescriptionSkipEmptyArchives bool = false + +@allowed([ + 'Compact' + 'Delete' +]) +@description('Optional. Retention cleanup policy. Enumerates the possible values for cleanup policy.') +param retentionDescriptionCleanupPolicy string = 'Delete' + +@minValue(1) +@maxValue(168) +@description('Optional. Retention time in hours. Number of hours to retain the events for this Event Hub. This value is only used when cleanupPolicy is Delete. If cleanupPolicy is Compact the returned value of this property is Long.MaxValue.') +param retentionDescriptionRetentionTimeInHours int = 1 + +@minValue(1) +@maxValue(168) +@description('Optional. Retention cleanup policy. Number of hours to retain the tombstone markers of a compacted Event Hub. This value is only used when cleanupPolicy is Compact. Consumer must complete reading the tombstone marker within this specified amount of time if consumer begins from starting offset to ensure they get a valid snapshot for the specific key described by the tombstone marker within the compacted Event Hub.') +param retentionDescriptionTombstoneRetentionTimeInHours int = 1 + +var eventHubProperties = { + messageRetentionInDays: messageRetentionInDays + partitionCount: partitionCount + status: status + retentionDescription: { + cleanupPolicy: retentionDescriptionCleanupPolicy + retentionTimeInHours: retentionDescriptionCleanupPolicy == 'Delete' ? retentionDescriptionRetentionTimeInHours : null + tombstoneRetentionTimeInHours: retentionDescriptionCleanupPolicy == 'Compact' ? retentionDescriptionTombstoneRetentionTimeInHours : null + } +} + +var eventHubPropertiesCapture = { + captureDescription: { + destination: { + name: captureDescriptionDestinationName + properties: { + archiveNameFormat: captureDescriptionDestinationArchiveNameFormat + blobContainer: captureDescriptionDestinationBlobContainer + storageAccountResourceId: captureDescriptionDestinationStorageAccountResourceId + } + } + enabled: captureDescriptionEnabled + encoding: captureDescriptionEncoding + intervalInSeconds: captureDescriptionIntervalInSeconds + sizeLimitInBytes: captureDescriptionSizeLimitInBytes + skipEmptyArchives: captureDescriptionSkipEmptyArchives + } +} + +var builtInRoleNames = { + 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') + 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') + 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource eventHub 'Microsoft.EventHub/namespaces/eventhubs@2022-10-01-preview' = { + name: name + parent: namespace + properties: captureDescriptionEnabled ? union(eventHubProperties, eventHubPropertiesCapture) : eventHubProperties +} + +resource eventHub_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: eventHub +} + +module eventHub_consumergroups 'consumergroup/main.bicep' = [for (consumerGroup, index) in consumergroups: { + name: '${deployment().name}-ConsumerGroup-${index}' + params: { + namespaceName: namespaceName + eventHubName: eventHub.name + name: consumerGroup.name + userMetadata: contains(consumerGroup, 'userMetadata') ? consumerGroup.userMetadata : '' + } +}] + +module eventHub_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { + name: '${deployment().name}-AuthRule-${index}' + params: { + namespaceName: namespaceName + eventHubName: eventHub.name + name: authorizationRule.name + rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] + } +}] + +resource eventHub_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(eventHub.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: eventHub +}] + +@description('The name of the event hub.') +output name string = eventHub.name + +@description('The resource ID of the event hub.') +output resourceId string = eventHub.id + +@description('The resource group the event hub was deployed into.') +output resourceGroupName string = resourceGroup().name + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? diff --git a/avm/res/event-hub/namespace/eventhub/main.json b/avm/res/event-hub/namespace/eventhub/main.json new file mode 100644 index 0000000000..57543ef237 --- /dev/null +++ b/avm/res/event-hub/namespace/eventhub/main.json @@ -0,0 +1,625 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "8657514846937945810" + }, + "name": "Event Hub Namespace Event Hubs", + "description": "This module deploys an Event Hub Namespace Event Hub.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the event hub." + } + }, + "authorizationRules": { + "type": "array", + "defaultValue": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + } + ], + "metadata": { + "description": "Optional. Authorization Rules for the event hub." + } + }, + "messageRetentionInDays": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 7, + "metadata": { + "description": "Optional. Number of days to retain the events for this Event Hub, value should be 1 to 7 days. Will be automatically set to infinite retention if cleanup policy is set to \"Compact\"." + } + }, + "partitionCount": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 32, + "metadata": { + "description": "Optional. Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions." + } + }, + "status": { + "type": "string", + "defaultValue": "Active", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" + ], + "metadata": { + "description": "Optional. Enumerates the possible values for the status of the Event Hub." + } + }, + "consumergroups": { + "type": "array", + "defaultValue": [ + { + "name": "$Default" + } + ], + "metadata": { + "description": "Optional. The consumer groups to create in this event hub instance." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "captureDescriptionDestinationName": { + "type": "string", + "defaultValue": "EventHubArchive.AzureBlockBlob", + "metadata": { + "description": "Optional. Name for capture destination." + } + }, + "captureDescriptionDestinationArchiveNameFormat": { + "type": "string", + "defaultValue": "{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}", + "metadata": { + "description": "Optional. Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}. Here all the parameters (Namespace,EventHub .. etc) are mandatory irrespective of order." + } + }, + "captureDescriptionDestinationBlobContainer": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Blob container Name." + } + }, + "captureDescriptionDestinationStorageAccountResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the storage account to be used to create the blobs." + } + }, + "captureDescriptionEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether capture description is enabled." + } + }, + "captureDescriptionEncoding": { + "type": "string", + "defaultValue": "Avro", + "allowedValues": [ + "Avro", + "AvroDeflate" + ], + "metadata": { + "description": "Optional. Enumerates the possible values for the encoding format of capture description. Note: \"AvroDeflate\" will be deprecated in New API Version." + } + }, + "captureDescriptionIntervalInSeconds": { + "type": "int", + "defaultValue": 300, + "minValue": 60, + "maxValue": 900, + "metadata": { + "description": "Optional. The time window allows you to set the frequency with which the capture to Azure Blobs will happen." + } + }, + "captureDescriptionSizeLimitInBytes": { + "type": "int", + "defaultValue": 314572800, + "minValue": 10485760, + "maxValue": 524288000, + "metadata": { + "description": "Optional. The size window defines the amount of data built up in your Event Hub before an capture operation." + } + }, + "captureDescriptionSkipEmptyArchives": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether to Skip Empty Archives." + } + }, + "retentionDescriptionCleanupPolicy": { + "type": "string", + "defaultValue": "Delete", + "allowedValues": [ + "Compact", + "Delete" + ], + "metadata": { + "description": "Optional. Retention cleanup policy. Enumerates the possible values for cleanup policy." + } + }, + "retentionDescriptionRetentionTimeInHours": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 168, + "metadata": { + "description": "Optional. Retention time in hours. Number of hours to retain the events for this Event Hub. This value is only used when cleanupPolicy is Delete. If cleanupPolicy is Compact the returned value of this property is Long.MaxValue." + } + }, + "retentionDescriptionTombstoneRetentionTimeInHours": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 168, + "metadata": { + "description": "Optional. Retention cleanup policy. Number of hours to retain the tombstone markers of a compacted Event Hub. This value is only used when cleanupPolicy is Compact. Consumer must complete reading the tombstone marker within this specified amount of time if consumer begins from starting offset to ensure they get a valid snapshot for the specific key described by the tombstone marker within the compacted Event Hub." + } + } + }, + "variables": { + "eventHubProperties": { + "messageRetentionInDays": "[parameters('messageRetentionInDays')]", + "partitionCount": "[parameters('partitionCount')]", + "status": "[parameters('status')]", + "retentionDescription": { + "cleanupPolicy": "[parameters('retentionDescriptionCleanupPolicy')]", + "retentionTimeInHours": "[if(equals(parameters('retentionDescriptionCleanupPolicy'), 'Delete'), parameters('retentionDescriptionRetentionTimeInHours'), null())]", + "tombstoneRetentionTimeInHours": "[if(equals(parameters('retentionDescriptionCleanupPolicy'), 'Compact'), parameters('retentionDescriptionTombstoneRetentionTimeInHours'), null())]" + } + }, + "eventHubPropertiesCapture": { + "captureDescription": { + "destination": { + "name": "[parameters('captureDescriptionDestinationName')]", + "properties": { + "archiveNameFormat": "[parameters('captureDescriptionDestinationArchiveNameFormat')]", + "blobContainer": "[parameters('captureDescriptionDestinationBlobContainer')]", + "storageAccountResourceId": "[parameters('captureDescriptionDestinationStorageAccountResourceId')]" + } + }, + "enabled": "[parameters('captureDescriptionEnabled')]", + "encoding": "[parameters('captureDescriptionEncoding')]", + "intervalInSeconds": "[parameters('captureDescriptionIntervalInSeconds')]", + "sizeLimitInBytes": "[parameters('captureDescriptionSizeLimitInBytes')]", + "skipEmptyArchives": "[parameters('captureDescriptionSkipEmptyArchives')]" + } + }, + "builtInRoleNames": { + "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", + "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", + "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "eventHub": { + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": "[if(parameters('captureDescriptionEnabled'), union(variables('eventHubProperties'), variables('eventHubPropertiesCapture')), variables('eventHubProperties'))]", + "dependsOn": [ + "namespace" + ] + }, + "eventHub_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}/eventhubs/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "eventHub" + ] + }, + "eventHub_roleAssignments": { + "copy": { + "name": "eventHub_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}/eventhubs/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[guid(resourceId('Microsoft.EventHub/namespaces/eventhubs', parameters('namespaceName'), parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "eventHub" + ] + }, + "eventHub_consumergroups": { + "copy": { + "name": "eventHub_consumergroups", + "count": "[length(parameters('consumergroups'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ConsumerGroup-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "eventHubName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('consumergroups')[copyIndex()].name]" + }, + "userMetadata": "[if(contains(parameters('consumergroups')[copyIndex()], 'userMetadata'), createObject('value', parameters('consumergroups')[copyIndex()].userMetadata), createObject('value', ''))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "697710281814211564" + }, + "name": "Event Hub Namespace Event Hub Consumer Groups", + "description": "This module deploys an Event Hub Namespace Event Hub Consumer Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.s." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the consumer group." + } + }, + "userMetadata": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. User Metadata is a placeholder to store user-defined string data with maximum length 1024. e.g. it can be used to store descriptive data, such as list of teams and their contact information also user-defined configuration settings can be stored." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/eventhubs/consumergroups", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "userMetadata": "[if(not(empty(parameters('userMetadata'))), parameters('userMetadata'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the consumer group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the consumer group." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs/consumergroups', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the consumer group was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHub" + ] + }, + "eventHub_authorizationRules": { + "copy": { + "name": "eventHub_authorizationRules", + "count": "[length(parameters('authorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-AuthRule-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "eventHubName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('authorizationRules')[copyIndex()].name]" + }, + "rights": "[if(contains(parameters('authorizationRules')[copyIndex()], 'rights'), createObject('value', parameters('authorizationRules')[copyIndex()].rights), createObject('value', createArray()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "16757979367783376523" + }, + "name": "Event Hub Namespace Event Hub Authorization Rules", + "description": "This module deploys an Event Hub Namespace Event Hub Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the authorization rule." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs/authorizationRules', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHub" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the event hub." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the event hub." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the event hub was deployed into." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/main.bicep b/avm/res/event-hub/namespace/main.bicep new file mode 100644 index 0000000000..86527fcf2c --- /dev/null +++ b/avm/res/event-hub/namespace/main.bicep @@ -0,0 +1,535 @@ +metadata name = 'Event Hub Namespaces' +metadata description = 'This module deploys an Event Hub Namespace.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the event hub namespace.') +@maxLength(50) +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. event hub plan SKU name.') +@allowed([ + 'Basic' + 'Standard' + 'Premium' +]) +param skuName string = 'Standard' + +@description('Optional. The Event Hub\'s throughput units for Basic or Standard tiers, where value should be 0 to 20 throughput units. The Event Hubs premium units for Premium tier, where value should be 0 to 10 premium units.') +@minValue(1) +@maxValue(20) +param skuCapacity int = 1 + +@description('Optional. Switch to make the Event Hub Namespace zone redundant.') +param zoneRedundant bool = false + +@description('Optional. Switch to enable the Auto Inflate feature of Event Hub. Auto Inflate is not supported in Premium SKU EventHub.') +param isAutoInflateEnabled bool = false + +@description('Optional. Upper limit of throughput units when AutoInflate is enabled, value should be within 0 to 20 throughput units.') +@minValue(0) +@maxValue(20) +param maximumThroughputUnits int = 1 + +@description('Optional. Authorization Rules for the Event Hub namespace.') +param authorizationRules array = [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } +] + +@description('Optional. This property disables SAS authentication for the Event Hubs namespace.') +param disableLocalAuth bool = true + +@description('Optional. Value that indicates whether Kafka is enabled for Event Hubs Namespace.') +param kafkaEnabled bool = false + +@allowed([ + '1.0' + '1.1' + '1.2' +]) +@description('Optional. The minimum TLS version for the cluster to support.') +param minimumTlsVersion string = '1.2' + +@description('Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set.') +@allowed([ + '' + 'Disabled' + 'Enabled' + 'SecuredByPerimeter' +]) +param publicNetworkAccess string = '' + +@description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') +param privateEndpoints privateEndpointType + +@description('Optional. Configure networking options. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace.') +param networkRuleSets object = {} + +@description('Optional. The diagnostic settings of the service.') +param diagnosticSettings diagnosticSettingType + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. The managed identity definition for this resource.') +param managedIdentities managedIdentitiesType + +@description('Optional. The customer managed key definition.') +param customerManagedKey customerManagedKeyType + +@description('Optional. Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters.') +param requireInfrastructureEncryption bool = false + +@description('Optional. Array of role assignments to create.') +param roleAssignments roleAssignmentType + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. Enable/Disable usage telemetry for module.') +param enableTelemetry bool = true + +@description('Optional. The event hubs to deploy into this namespace.') +param eventhubs array = [] + +@description('Optional. The disaster recovery config for this namespace.') +param disasterRecoveryConfig object = {} + +var maximumThroughputUnitsVar = !isAutoInflateEnabled ? 0 : maximumThroughputUnits + +var formattedUserAssignedIdentities = reduce(map((managedIdentities.?userAssignedResourceIds ?? []), (id) => { '${id}': {} }), {}, (cur, next) => union(cur, next)) // Converts the flat array to an object like { '${id1}': {}, '${id2}': {} } + +var identity = !empty(managedIdentities) ? { + type: (managedIdentities.?systemAssigned ?? false) ? (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : (!empty(managedIdentities.?userAssignedResourceIds ?? {}) ? 'UserAssigned' : 'None') + userAssignedIdentities: !empty(formattedUserAssignedIdentities) ? formattedUserAssignedIdentities : null +} : null + +var builtInRoleNames = { + 'Azure Event Hubs Data Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec') + 'Azure Event Hubs Data Receiver': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde') + 'Azure Event Hubs Data Sender': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975') + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') +} + +resource cMKKeyVault 'Microsoft.KeyVault/vaults@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId)) { + name: last(split((customerManagedKey.?keyVaultResourceId ?? 'dummyVault'), '/')) + scope: resourceGroup(split((customerManagedKey.?keyVaultResourceId ?? '//'), '/')[2], split((customerManagedKey.?keyVaultResourceId ?? '////'), '/')[4]) + + resource cMKKey 'keys@2023-02-01' existing = if (!empty(customerManagedKey.?keyVaultResourceId) && !empty(customerManagedKey.?keyName)) { + name: customerManagedKey.?keyName ?? 'dummyKey' + } +} + +resource cMKUserAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' existing = if (!empty(customerManagedKey.?userAssignedIdentityResourceId)) { + name: last(split(customerManagedKey.?userAssignedIdentityResourceId ?? 'dummyMsi', '/')) + scope: resourceGroup(split((customerManagedKey.?userAssignedIdentityResourceId ?? '//'), '/')[2], split((customerManagedKey.?userAssignedIdentityResourceId ?? '////'), '/')[4]) +} + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: '46d3xbcp.res.eventhub-namespace.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + + +resource eventHubNamespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' = { + name: name + location: location + tags: tags + identity: identity + sku: { + name: skuName + tier: skuName + capacity: skuCapacity + } + properties: { + disableLocalAuth: disableLocalAuth + encryption: !empty(customerManagedKey) ? { + keySource: 'Microsoft.KeyVault' + keyVaultProperties: [ + { + identity: !empty(customerManagedKey.?userAssignedIdentityResourceId) ? { + userAssignedIdentity: cMKUserAssignedIdentity.id + } : null + keyName: customerManagedKey!.keyName + keyVaultUri: cMKKeyVault.properties.vaultUri + keyVersion: !empty(customerManagedKey.?keyVersion ?? '') ? customerManagedKey!.keyVersion : last(split(cMKKeyVault::cMKKey.properties.keyUriWithVersion, '/')) + } + ] + requireInfrastructureEncryption: requireInfrastructureEncryption + } : null + isAutoInflateEnabled: isAutoInflateEnabled + kafkaEnabled: kafkaEnabled + maximumThroughputUnits: maximumThroughputUnitsVar + minimumTlsVersion: minimumTlsVersion + publicNetworkAccess: contains(networkRuleSets, 'publicNetworkAccess') ? networkRuleSets.publicNetworkAccess : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : publicNetworkAccess) + zoneRedundant: zoneRedundant + } +} + +module eventHubNamespace_authorizationRules 'authorization-rule/main.bicep' = [for (authorizationRule, index) in authorizationRules: { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-AuthRule-${index}' + params: { + namespaceName: eventHubNamespace.name + name: authorizationRule.name + rights: contains(authorizationRule, 'rights') ? authorizationRule.rights : [] + } +}] + +module eventHubNamespace_disasterRecoveryConfig 'disaster-recovery-config/main.bicep' = if (!empty(disasterRecoveryConfig)) { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-DisRecConfig' + params: { + namespaceName: eventHubNamespace.name + name: disasterRecoveryConfig.name + partnerNamespaceId: contains(disasterRecoveryConfig, 'partnerNamespaceId') ? disasterRecoveryConfig.partnerNamespaceId : '' + } +} + +module eventHubNamespace_eventhubs 'eventhub/main.bicep' = [for (eventHub, index) in eventhubs: { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-EventHub-${index}' + params: { + namespaceName: eventHubNamespace.name + name: eventHub.name + authorizationRules: contains(eventHub, 'authorizationRules') ? eventHub.authorizationRules : [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: contains(eventHub, 'captureDescriptionDestinationArchiveNameFormat') ? eventHub.captureDescriptionDestinationArchiveNameFormat : '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: contains(eventHub, 'captureDescriptionDestinationBlobContainer') ? eventHub.captureDescriptionDestinationBlobContainer : '' + captureDescriptionDestinationName: contains(eventHub, 'captureDescriptionDestinationName') ? eventHub.captureDescriptionDestinationName : 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: contains(eventHub, 'captureDescriptionDestinationStorageAccountResourceId') ? eventHub.captureDescriptionDestinationStorageAccountResourceId : '' + captureDescriptionEnabled: contains(eventHub, 'captureDescriptionEnabled') ? eventHub.captureDescriptionEnabled : false + captureDescriptionEncoding: contains(eventHub, 'captureDescriptionEncoding') ? eventHub.captureDescriptionEncoding : 'Avro' + captureDescriptionIntervalInSeconds: contains(eventHub, 'captureDescriptionIntervalInSeconds') ? eventHub.captureDescriptionIntervalInSeconds : 300 + captureDescriptionSizeLimitInBytes: contains(eventHub, 'captureDescriptionSizeLimitInBytes') ? eventHub.captureDescriptionSizeLimitInBytes : 314572800 + captureDescriptionSkipEmptyArchives: contains(eventHub, 'captureDescriptionSkipEmptyArchives') ? eventHub.captureDescriptionSkipEmptyArchives : false + consumergroups: contains(eventHub, 'consumergroups') ? eventHub.consumergroups : [] + lock: eventHub.?lock ?? lock + messageRetentionInDays: contains(eventHub, 'messageRetentionInDays') ? eventHub.messageRetentionInDays : 1 + partitionCount: contains(eventHub, 'partitionCount') ? eventHub.partitionCount : 2 + roleAssignments: contains(eventHub, 'roleAssignments') ? eventHub.roleAssignments : [] + status: contains(eventHub, 'status') ? eventHub.status : 'Active' + retentionDescriptionCleanupPolicy: contains(eventHub, 'retentionDescriptionCleanupPolicy') ? eventHub.retentionDescriptionCleanupPolicy : 'Delete' + retentionDescriptionRetentionTimeInHours: contains(eventHub, 'retentionDescriptionRetentionTimeInHours') ? eventHub.retentionDescriptionRetentionTimeInHours : 1 + retentionDescriptionTombstoneRetentionTimeInHours: contains(eventHub, 'retentionDescriptionTombstoneRetentionTimeInHours') ? eventHub.retentionDescriptionTombstoneRetentionTimeInHours : 1 + } +}] + +module eventHubNamespace_networkRuleSet 'network-rule-set/main.bicep' = if (!empty(networkRuleSets) || !empty(privateEndpoints)) { + name: '${uniqueString(deployment().name, location)}-EvhbNamespace-NetworkRuleSet' + params: { + namespaceName: eventHubNamespace.name + publicNetworkAccess: contains(networkRuleSets, 'publicNetworkAccess') ? networkRuleSets.publicNetworkAccess : (!empty(privateEndpoints) && empty(networkRuleSets) ? 'Disabled' : 'Enabled') + defaultAction: contains(networkRuleSets, 'defaultAction') ? networkRuleSets.defaultAction : 'Allow' + trustedServiceAccessEnabled: networkRuleSets.?trustedServiceAccessEnabled + ipRules: contains(networkRuleSets, 'ipRules') ? networkRuleSets.ipRules : [] + virtualNetworkRules: contains(networkRuleSets, 'virtualNetworkRules') ? networkRuleSets.virtualNetworkRules : [] + } +} + +module eventHubNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [for (privateEndpoint, index) in (privateEndpoints ?? []): { + name: '${uniqueString(deployment().name, location)}-EventHubNamespace-PrivateEndpoint-${index}' + params: { + name: privateEndpoint.?name ?? 'pep-${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: eventHubNamespace.id + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + } + } + ] : null + manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true ? [ + { + name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(eventHubNamespace.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' + properties: { + privateLinkServiceId: eventHubNamespace.id + groupIds: [ + privateEndpoint.?service ?? 'namespace' + ] + requestMessage: privateEndpoint.?manualConnectionRequestMessage ?? 'Manual approval required.' + } + } + ] : null + subnetResourceId: privateEndpoint.subnetResourceId + enableTelemetry: privateEndpoint.?enableTelemetry ?? enableTelemetry + location: privateEndpoint.?location ?? reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location + lock: privateEndpoint.?lock ?? lock + privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName + privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + roleAssignments: privateEndpoint.?roleAssignments + tags: privateEndpoint.?tags ?? tags + customDnsConfigs: privateEndpoint.?customDnsConfigs + ipConfigurations: privateEndpoint.?ipConfigurations + applicationSecurityGroupResourceIds: privateEndpoint.?applicationSecurityGroupResourceIds + customNetworkInterfaceName: privateEndpoint.?customNetworkInterfaceName + } +}] + +resource eventHubNamespace_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(eventHubNamespace.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : contains(roleAssignment.roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/') ? roleAssignment.roleDefinitionIdOrName : subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleAssignment.roleDefinitionIdOrName) + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId + } + scope: eventHubNamespace +}] + +resource eventHubNamespace_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: eventHubNamespace +} + +resource eventHubNamespace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = [for (diagnosticSetting, index) in (diagnosticSettings ?? []): { + name: diagnosticSetting.?name ?? '${name}-diagnosticSettings' + properties: { + storageAccountId: diagnosticSetting.?storageAccountResourceId + workspaceId: diagnosticSetting.?workspaceResourceId + eventHubAuthorizationRuleId: diagnosticSetting.?eventHubAuthorizationRuleResourceId + eventHubName: diagnosticSetting.?eventHubName + metrics: [for group in (diagnosticSetting.?metricCategories ?? [ { category: 'AllMetrics' } ]): { + category: group.category + enabled: group.?enabled ?? true + timeGrain: null + }] + logs: [for group in (diagnosticSetting.?logCategoriesAndGroups ?? [ { categoryGroup: 'allLogs' } ]): { + categoryGroup: group.?categoryGroup + category: group.?category + enabled: group.?enabled ?? true + }] + marketplacePartnerId: diagnosticSetting.?marketplacePartnerResourceId + logAnalyticsDestinationType: diagnosticSetting.?logAnalyticsDestinationType + } + scope: eventHubNamespace +}] + +@description('The name of the eventspace.') +output name string = eventHubNamespace.name + +@description('The resource ID of the eventspace.') +output resourceId string = eventHubNamespace.id + +@description('The resource group where the namespace is deployed.') +output resourceGroupName string = resourceGroup().name + +@description('The principal ID of the system assigned identity.') +output systemAssignedMIPrincipalId string = eventHubNamespace.?identity.?principalId ?? '' + +@description('The location the resource was deployed into.') +output location string = eventHubNamespace.location + +// =============== // +// Definitions // +// =============== // + +type managedIdentitiesType = { + @description('Optional. Enables system assigned managed identity on the resource.') + systemAssigned: bool? + + @description('Optional. The resource ID(s) to assign to the resource.') + userAssignedResourceIds: string[]? +}? + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? + +type roleAssignmentType = { + @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') + roleDefinitionIdOrName: string + + @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') + principalId: string + + @description('Optional. The principal type of the assigned principal ID.') + principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? + + @description('Optional. The description of the role assignment.') + description: string? + + @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') + condition: string? + + @description('Optional. Version of the condition.') + conditionVersion: '2.0'? + + @description('Optional. The Resource Id of the delegated managed identity resource.') + delegatedManagedIdentityResourceId: string? +}[]? + +type privateEndpointType = { + @description('Optional. The name of the private endpoint.') + name: string? + + @description('Optional. The location to deploy the private endpoint to.') + location: string? + + @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') + service: string? + + @description('Required. Resource ID of the subnet where the endpoint needs to be created.') + subnetResourceId: string + + @description('Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided.') + privateDnsZoneGroupName: string? + + @description('Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneResourceIds: string[]? + + @description('Optional. If Manual Private Link Connection is required.') + isManualConnection: bool? + + @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') + @maxLength(140) + manualConnectionRequestMessage: string? + + @description('Optional. Custom DNS configurations.') + customDnsConfigs: { + @description('Required. Fqdn that resolves to private endpoint IP address.') + fqdn: string? + + @description('Required. A list of private IP addresses of the private endpoint.') + ipAddresses: string[] + }[]? + + @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') + ipConfigurations: { + @description('Required. The name of the resource that is unique within a resource group.') + name: string + + @description('Required. Properties of private endpoint IP configurations.') + properties: { + @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') + groupId: string + + @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') + memberName: string + + @description('Required. A private IP address obtained from the private endpoint\'s subnet.') + privateIPAddress: string + } + }[]? + + @description('Optional. Application security groups in which the private endpoint IP configuration is included.') + applicationSecurityGroupResourceIds: string[]? + + @description('Optional. The custom name of the network interface attached to the private endpoint.') + customNetworkInterfaceName: string? + + @description('Optional. Specify the type of lock.') + lock: lockType + + @description('Optional. Array of role assignments to create.') + roleAssignments: roleAssignmentType + + @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') + tags: object? + + @description('Optional. Enable/Disable usage telemetry for module.') + enableTelemetry: bool? +}[]? + +type diagnosticSettingType = { + @description('Optional. The name of diagnostic setting.') + name: string? + + @description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource. Set to `[]` to disable log collection.') + logCategoriesAndGroups: { + @description('Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here.') + category: string? + + @description('Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs.') + categoryGroup: string? + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? + }[]? + + @description('Optional. The name of metrics that will be streamed. "allMetrics" includes all possible metrics for the resource. Set to `[]` to disable metric collection.') + metricCategories: { + @description('Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics.') + category: string + + @description('Optional. Enable or disable the category explicitly. Default is `true`.') + enabled: bool? + }[]? + + @description('Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type.') + logAnalyticsDestinationType: ('Dedicated' | 'AzureDiagnostics')? + + @description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + workspaceResourceId: string? + + @description('Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + storageAccountResourceId: string? + + @description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') + eventHubAuthorizationRuleResourceId: string? + + @description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.') + eventHubName: string? + + @description('Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs.') + marketplacePartnerResourceId: string? +}[]? + +type customerManagedKeyType = { + @description('Required. The resource ID of a key vault to reference a customer managed key for encryption from.') + keyVaultResourceId: string + + @description('Required. The name of the customer managed key to use for encryption.') + keyName: string + + @description('Optional. The version of the customer managed key to reference for encryption. If not provided, using \'latest\'.') + keyVersion: string? + + @description('Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use.') + userAssignedIdentityResourceId: string? +}? diff --git a/avm/res/event-hub/namespace/main.json b/avm/res/event-hub/namespace/main.json new file mode 100644 index 0000000000..7b4d5d960f --- /dev/null +++ b/avm/res/event-hub/namespace/main.json @@ -0,0 +1,2540 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "2606348480823352941" + }, + "name": "Event Hub Namespaces", + "description": "This module deploys an Event Hub Namespace.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "managedIdentitiesType": { + "type": "object", + "properties": { + "systemAssigned": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enables system assigned managed identity on the resource." + } + }, + "userAssignedResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The resource ID(s) to assign to the resource." + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "privateEndpointType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the private endpoint to." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + } + }, + "nullable": true + }, + "diagnosticSettingType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of diagnostic setting." + } + }, + "logCategoriesAndGroups": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category for a resource type this setting is applied to. Set the specific logs to collect here." + } + }, + "categoryGroup": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of a Diagnostic Log category group for a resource type this setting is applied to. Set to `allLogs` to collect all logs." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource. Set to `[]` to disable log collection." + } + }, + "metricCategories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "category": { + "type": "string", + "metadata": { + "description": "Required. Name of a Diagnostic Metric category for a resource type this setting is applied to. Set to `AllMetrics` to collect all metrics." + } + }, + "enabled": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable or disable the category explicitly. Default is `true`." + } + } + } + }, + "nullable": true, + "metadata": { + "description": "Optional. The name of metrics that will be streamed. \"allMetrics\" includes all possible metrics for the resource. Set to `[]` to disable metric collection." + } + }, + "logAnalyticsDestinationType": { + "type": "string", + "allowedValues": [ + "AzureDiagnostics", + "Dedicated" + ], + "nullable": true, + "metadata": { + "description": "Optional. A string indicating whether the export to Log Analytics should use the default destination type, i.e. AzureDiagnostics, or use a destination type." + } + }, + "workspaceResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "storageAccountResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic storage account. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "eventHubAuthorizationRuleResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to." + } + }, + "eventHubName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub." + } + }, + "marketplacePartnerResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The full ARM resource ID of the Marketplace resource to which you would like to send Diagnostic Logs." + } + } + } + }, + "nullable": true + }, + "customerManagedKeyType": { + "type": "object", + "properties": { + "keyVaultResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a key vault to reference a customer managed key for encryption from." + } + }, + "keyName": { + "type": "string", + "metadata": { + "description": "Required. The name of the customer managed key to use for encryption." + } + }, + "keyVersion": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The version of the customer managed key to reference for encryption. If not provided, using 'latest'." + } + }, + "userAssignedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. User assigned identity to use when fetching the customer managed key. Required if no system assigned identity is available for use." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "maxLength": 50, + "metadata": { + "description": "Required. The name of the event hub namespace." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all resources." + } + }, + "skuName": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Basic", + "Standard", + "Premium" + ], + "metadata": { + "description": "Optional. event hub plan SKU name." + } + }, + "skuCapacity": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 20, + "metadata": { + "description": "Optional. The Event Hub's throughput units for Basic or Standard tiers, where value should be 0 to 20 throughput units. The Event Hubs premium units for Premium tier, where value should be 0 to 10 premium units." + } + }, + "zoneRedundant": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Switch to make the Event Hub Namespace zone redundant." + } + }, + "isAutoInflateEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Switch to enable the Auto Inflate feature of Event Hub. Auto Inflate is not supported in Premium SKU EventHub." + } + }, + "maximumThroughputUnits": { + "type": "int", + "defaultValue": 1, + "minValue": 0, + "maxValue": 20, + "metadata": { + "description": "Optional. Upper limit of throughput units when AutoInflate is enabled, value should be within 0 to 20 throughput units." + } + }, + "authorizationRules": { + "type": "array", + "defaultValue": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + } + ], + "metadata": { + "description": "Optional. Authorization Rules for the Event Hub namespace." + } + }, + "disableLocalAuth": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. This property disables SAS authentication for the Event Hubs namespace." + } + }, + "kafkaEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Value that indicates whether Kafka is enabled for Event Hubs Namespace." + } + }, + "minimumTlsVersion": { + "type": "string", + "defaultValue": "1.2", + "allowedValues": [ + "1.0", + "1.1", + "1.2" + ], + "metadata": { + "description": "Optional. The minimum TLS version for the cluster to support." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Disabled", + "Enabled", + "SecuredByPerimeter" + ], + "metadata": { + "description": "Optional. Whether or not public network access is allowed for this resource. For security reasons it should be disabled. If not specified, it will be disabled by default if private endpoints are set." + } + }, + "privateEndpoints": { + "$ref": "#/definitions/privateEndpointType", + "metadata": { + "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." + } + }, + "networkRuleSets": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Configure networking options. This object contains IPs/Subnets to allow or restrict access to private endpoints only. For security reasons, it is recommended to configure this object on the Namespace." + } + }, + "diagnosticSettings": { + "$ref": "#/definitions/diagnosticSettingType", + "metadata": { + "description": "Optional. The diagnostic settings of the service." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "managedIdentities": { + "$ref": "#/definitions/managedIdentitiesType", + "metadata": { + "description": "Optional. The managed identity definition for this resource." + } + }, + "customerManagedKey": { + "$ref": "#/definitions/customerManagedKeyType", + "metadata": { + "description": "Optional. The customer managed key definition." + } + }, + "requireInfrastructureEncryption": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable infrastructure encryption (double encryption). Note, this setting requires the configuration of Customer-Managed-Keys (CMK) via the corresponding module parameters." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + }, + "eventhubs": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The event hubs to deploy into this namespace." + } + }, + "disasterRecoveryConfig": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. The disaster recovery config for this namespace." + } + } + }, + "variables": { + "maximumThroughputUnitsVar": "[if(not(parameters('isAutoInflateEnabled')), 0, parameters('maximumThroughputUnits'))]", + "formattedUserAssignedIdentities": "[reduce(map(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createArray()), lambda('id', createObject(format('{0}', lambdaVariables('id')), createObject()))), createObject(), lambda('cur', 'next', union(lambdaVariables('cur'), lambdaVariables('next'))))]", + "identity": "[if(not(empty(parameters('managedIdentities'))), createObject('type', if(coalesce(tryGet(parameters('managedIdentities'), 'systemAssigned'), false()), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'SystemAssigned, UserAssigned', 'SystemAssigned'), if(not(empty(coalesce(tryGet(parameters('managedIdentities'), 'userAssignedResourceIds'), createObject()))), 'UserAssigned', 'None')), 'userAssignedIdentities', if(not(empty(variables('formattedUserAssignedIdentities'))), variables('formattedUserAssignedIdentities'), null())), null())]", + "builtInRoleNames": { + "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", + "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", + "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "cMKKeyVault::cMKKey": { + "condition": "[and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), and(not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'))), not(empty(tryGet(parameters('customerManagedKey'), 'keyName')))))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[format('{0}/{1}', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/')), coalesce(tryGet(parameters('customerManagedKey'), 'keyName'), 'dummyKey'))]", + "dependsOn": [ + "cMKKeyVault" + ] + }, + "cMKKeyVault": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId')))]", + "existing": true, + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2023-02-01", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'keyVaultResourceId'), 'dummyVault'), '/'))]" + }, + "cMKUserAssignedIdentity": { + "condition": "[not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId')))]", + "existing": true, + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "subscriptionId": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2]]", + "resourceGroup": "[split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]]", + "name": "[last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/'))]" + }, + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.eventhub-namespace.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "eventHubNamespace": { + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "identity": "[variables('identity')]", + "sku": { + "name": "[parameters('skuName')]", + "tier": "[parameters('skuName')]", + "capacity": "[parameters('skuCapacity')]" + }, + "properties": { + "disableLocalAuth": "[parameters('disableLocalAuth')]", + "encryption": "[if(not(empty(parameters('customerManagedKey'))), createObject('keySource', 'Microsoft.KeyVault', 'keyVaultProperties', createArray(createObject('identity', if(not(empty(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'))), createObject('userAssignedIdentity', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '//'), '/')[2], split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), '////'), '/')[4]), 'Microsoft.ManagedIdentity/userAssignedIdentities', last(split(coalesce(tryGet(parameters('customerManagedKey'), 'userAssignedIdentityResourceId'), 'dummyMsi'), '/')))), null()), 'keyName', parameters('customerManagedKey').keyName, 'keyVaultUri', reference('cMKKeyVault').vaultUri, 'keyVersion', if(not(empty(coalesce(tryGet(parameters('customerManagedKey'), 'keyVersion'), ''))), parameters('customerManagedKey').keyVersion, last(split(reference('cMKKeyVault::cMKKey').keyUriWithVersion, '/'))))), 'requireInfrastructureEncryption', parameters('requireInfrastructureEncryption')), null())]", + "isAutoInflateEnabled": "[parameters('isAutoInflateEnabled')]", + "kafkaEnabled": "[parameters('kafkaEnabled')]", + "maximumThroughputUnits": "[variables('maximumThroughputUnitsVar')]", + "minimumTlsVersion": "[parameters('minimumTlsVersion')]", + "publicNetworkAccess": "[if(contains(parameters('networkRuleSets'), 'publicNetworkAccess'), parameters('networkRuleSets').publicNetworkAccess, if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSets'))), 'Disabled', parameters('publicNetworkAccess')))]", + "zoneRedundant": "[parameters('zoneRedundant')]" + }, + "dependsOn": [ + "cMKKeyVault", + "cMKUserAssignedIdentity" + ] + }, + "eventHubNamespace_roleAssignments": { + "copy": { + "name": "eventHubNamespace_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.EventHub/namespaces', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_diagnosticSettings": { + "copy": { + "name": "eventHubNamespace_diagnosticSettings", + "count": "[length(coalesce(parameters('diagnosticSettings'), createArray()))]" + }, + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.EventHub/namespaces/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'name'), format('{0}-diagnosticSettings', parameters('name')))]", + "properties": { + "copy": [ + { + "name": "metrics", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics'))))]", + "input": { + "category": "[coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')].category]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'metricCategories'), createArray(createObject('category', 'AllMetrics')))[copyIndex('metrics')], 'enabled'), true())]", + "timeGrain": null + } + }, + { + "name": "logs", + "count": "[length(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs'))))]", + "input": { + "categoryGroup": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'categoryGroup')]", + "category": "[tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'category')]", + "enabled": "[coalesce(tryGet(coalesce(tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logCategoriesAndGroups'), createArray(createObject('categoryGroup', 'allLogs')))[copyIndex('logs')], 'enabled'), true())]" + } + } + ], + "storageAccountId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'storageAccountResourceId')]", + "workspaceId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'workspaceResourceId')]", + "eventHubAuthorizationRuleId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubAuthorizationRuleResourceId')]", + "eventHubName": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'eventHubName')]", + "marketplacePartnerId": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'marketplacePartnerResourceId')]", + "logAnalyticsDestinationType": "[tryGet(coalesce(parameters('diagnosticSettings'), createArray())[copyIndex()], 'logAnalyticsDestinationType')]" + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_authorizationRules": { + "copy": { + "name": "eventHubNamespace_authorizationRules", + "count": "[length(parameters('authorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-EvhbNamespace-AuthRule-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('authorizationRules')[copyIndex()].name]" + }, + "rights": "[if(contains(parameters('authorizationRules')[copyIndex()], 'rights'), createObject('value', parameters('authorizationRules')[copyIndex()].rights), createObject('value', createArray()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "10638309014943371587" + }, + "name": "Event Hub Namespace Authorization Rule", + "description": "This module deploys an Event Hub Namespace Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the authorization rule." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/authorizationRules', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_disasterRecoveryConfig": { + "condition": "[not(empty(parameters('disasterRecoveryConfig')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-EvhbNamespace-DisRecConfig', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('disasterRecoveryConfig').name]" + }, + "partnerNamespaceId": "[if(contains(parameters('disasterRecoveryConfig'), 'partnerNamespaceId'), createObject('value', parameters('disasterRecoveryConfig').partnerNamespaceId), createObject('value', ''))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "14933577565840576961" + }, + "name": "Event Hub Namespace Disaster Recovery Configs", + "description": "This module deploys an Event Hub Namespace Disaster Recovery Config.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the disaster recovery config." + } + }, + "partnerNamespaceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the Primary/Secondary event hub namespace name, which is part of GEO DR pairing." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/disasterRecoveryConfigs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": { + "partnerNamespace": "[parameters('partnerNamespaceId')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the disaster recovery config." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the disaster recovery config." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/disasterRecoveryConfigs', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the disaster recovery config was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_eventhubs": { + "copy": { + "name": "eventHubNamespace_eventhubs", + "count": "[length(parameters('eventhubs'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-EvhbNamespace-EventHub-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('eventhubs')[copyIndex()].name]" + }, + "authorizationRules": "[if(contains(parameters('eventhubs')[copyIndex()], 'authorizationRules'), createObject('value', parameters('eventhubs')[copyIndex()].authorizationRules), createObject('value', createArray(createObject('name', 'RootManageSharedAccessKey', 'rights', createArray('Listen', 'Manage', 'Send')))))]", + "captureDescriptionDestinationArchiveNameFormat": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionDestinationArchiveNameFormat'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionDestinationArchiveNameFormat), createObject('value', '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}'))]", + "captureDescriptionDestinationBlobContainer": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionDestinationBlobContainer'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionDestinationBlobContainer), createObject('value', ''))]", + "captureDescriptionDestinationName": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionDestinationName'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionDestinationName), createObject('value', 'EventHubArchive.AzureBlockBlob'))]", + "captureDescriptionDestinationStorageAccountResourceId": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionDestinationStorageAccountResourceId'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionDestinationStorageAccountResourceId), createObject('value', ''))]", + "captureDescriptionEnabled": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionEnabled'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionEnabled), createObject('value', false()))]", + "captureDescriptionEncoding": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionEncoding'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionEncoding), createObject('value', 'Avro'))]", + "captureDescriptionIntervalInSeconds": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionIntervalInSeconds'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionIntervalInSeconds), createObject('value', 300))]", + "captureDescriptionSizeLimitInBytes": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionSizeLimitInBytes'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionSizeLimitInBytes), createObject('value', 314572800))]", + "captureDescriptionSkipEmptyArchives": "[if(contains(parameters('eventhubs')[copyIndex()], 'captureDescriptionSkipEmptyArchives'), createObject('value', parameters('eventhubs')[copyIndex()].captureDescriptionSkipEmptyArchives), createObject('value', false()))]", + "consumergroups": "[if(contains(parameters('eventhubs')[copyIndex()], 'consumergroups'), createObject('value', parameters('eventhubs')[copyIndex()].consumergroups), createObject('value', createArray()))]", + "lock": { + "value": "[coalesce(tryGet(parameters('eventhubs')[copyIndex()], 'lock'), parameters('lock'))]" + }, + "messageRetentionInDays": "[if(contains(parameters('eventhubs')[copyIndex()], 'messageRetentionInDays'), createObject('value', parameters('eventhubs')[copyIndex()].messageRetentionInDays), createObject('value', 1))]", + "partitionCount": "[if(contains(parameters('eventhubs')[copyIndex()], 'partitionCount'), createObject('value', parameters('eventhubs')[copyIndex()].partitionCount), createObject('value', 2))]", + "roleAssignments": "[if(contains(parameters('eventhubs')[copyIndex()], 'roleAssignments'), createObject('value', parameters('eventhubs')[copyIndex()].roleAssignments), createObject('value', createArray()))]", + "status": "[if(contains(parameters('eventhubs')[copyIndex()], 'status'), createObject('value', parameters('eventhubs')[copyIndex()].status), createObject('value', 'Active'))]", + "retentionDescriptionCleanupPolicy": "[if(contains(parameters('eventhubs')[copyIndex()], 'retentionDescriptionCleanupPolicy'), createObject('value', parameters('eventhubs')[copyIndex()].retentionDescriptionCleanupPolicy), createObject('value', 'Delete'))]", + "retentionDescriptionRetentionTimeInHours": "[if(contains(parameters('eventhubs')[copyIndex()], 'retentionDescriptionRetentionTimeInHours'), createObject('value', parameters('eventhubs')[copyIndex()].retentionDescriptionRetentionTimeInHours), createObject('value', 1))]", + "retentionDescriptionTombstoneRetentionTimeInHours": "[if(contains(parameters('eventhubs')[copyIndex()], 'retentionDescriptionTombstoneRetentionTimeInHours'), createObject('value', parameters('eventhubs')[copyIndex()].retentionDescriptionTombstoneRetentionTimeInHours), createObject('value', 1))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "8657514846937945810" + }, + "name": "Event Hub Namespace Event Hubs", + "description": "This module deploys an Event Hub Namespace Event Hub.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the event hub." + } + }, + "authorizationRules": { + "type": "array", + "defaultValue": [ + { + "name": "RootManageSharedAccessKey", + "rights": [ + "Listen", + "Manage", + "Send" + ] + } + ], + "metadata": { + "description": "Optional. Authorization Rules for the event hub." + } + }, + "messageRetentionInDays": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 7, + "metadata": { + "description": "Optional. Number of days to retain the events for this Event Hub, value should be 1 to 7 days. Will be automatically set to infinite retention if cleanup policy is set to \"Compact\"." + } + }, + "partitionCount": { + "type": "int", + "defaultValue": 2, + "minValue": 1, + "maxValue": 32, + "metadata": { + "description": "Optional. Number of partitions created for the Event Hub, allowed values are from 1 to 32 partitions." + } + }, + "status": { + "type": "string", + "defaultValue": "Active", + "allowedValues": [ + "Active", + "Creating", + "Deleting", + "Disabled", + "ReceiveDisabled", + "Renaming", + "Restoring", + "SendDisabled", + "Unknown" + ], + "metadata": { + "description": "Optional. Enumerates the possible values for the status of the Event Hub." + } + }, + "consumergroups": { + "type": "array", + "defaultValue": [ + { + "name": "$Default" + } + ], + "metadata": { + "description": "Optional. The consumer groups to create in this event hub instance." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "captureDescriptionDestinationName": { + "type": "string", + "defaultValue": "EventHubArchive.AzureBlockBlob", + "metadata": { + "description": "Optional. Name for capture destination." + } + }, + "captureDescriptionDestinationArchiveNameFormat": { + "type": "string", + "defaultValue": "{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}", + "metadata": { + "description": "Optional. Blob naming convention for archive, e.g. {Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}. Here all the parameters (Namespace,EventHub .. etc) are mandatory irrespective of order." + } + }, + "captureDescriptionDestinationBlobContainer": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Blob container Name." + } + }, + "captureDescriptionDestinationStorageAccountResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Resource ID of the storage account to be used to create the blobs." + } + }, + "captureDescriptionEnabled": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether capture description is enabled." + } + }, + "captureDescriptionEncoding": { + "type": "string", + "defaultValue": "Avro", + "allowedValues": [ + "Avro", + "AvroDeflate" + ], + "metadata": { + "description": "Optional. Enumerates the possible values for the encoding format of capture description. Note: \"AvroDeflate\" will be deprecated in New API Version." + } + }, + "captureDescriptionIntervalInSeconds": { + "type": "int", + "defaultValue": 300, + "minValue": 60, + "maxValue": 900, + "metadata": { + "description": "Optional. The time window allows you to set the frequency with which the capture to Azure Blobs will happen." + } + }, + "captureDescriptionSizeLimitInBytes": { + "type": "int", + "defaultValue": 314572800, + "minValue": 10485760, + "maxValue": 524288000, + "metadata": { + "description": "Optional. The size window defines the amount of data built up in your Event Hub before an capture operation." + } + }, + "captureDescriptionSkipEmptyArchives": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. A value that indicates whether to Skip Empty Archives." + } + }, + "retentionDescriptionCleanupPolicy": { + "type": "string", + "defaultValue": "Delete", + "allowedValues": [ + "Compact", + "Delete" + ], + "metadata": { + "description": "Optional. Retention cleanup policy. Enumerates the possible values for cleanup policy." + } + }, + "retentionDescriptionRetentionTimeInHours": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 168, + "metadata": { + "description": "Optional. Retention time in hours. Number of hours to retain the events for this Event Hub. This value is only used when cleanupPolicy is Delete. If cleanupPolicy is Compact the returned value of this property is Long.MaxValue." + } + }, + "retentionDescriptionTombstoneRetentionTimeInHours": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "maxValue": 168, + "metadata": { + "description": "Optional. Retention cleanup policy. Number of hours to retain the tombstone markers of a compacted Event Hub. This value is only used when cleanupPolicy is Compact. Consumer must complete reading the tombstone marker within this specified amount of time if consumer begins from starting offset to ensure they get a valid snapshot for the specific key described by the tombstone marker within the compacted Event Hub." + } + } + }, + "variables": { + "eventHubProperties": { + "messageRetentionInDays": "[parameters('messageRetentionInDays')]", + "partitionCount": "[parameters('partitionCount')]", + "status": "[parameters('status')]", + "retentionDescription": { + "cleanupPolicy": "[parameters('retentionDescriptionCleanupPolicy')]", + "retentionTimeInHours": "[if(equals(parameters('retentionDescriptionCleanupPolicy'), 'Delete'), parameters('retentionDescriptionRetentionTimeInHours'), null())]", + "tombstoneRetentionTimeInHours": "[if(equals(parameters('retentionDescriptionCleanupPolicy'), 'Compact'), parameters('retentionDescriptionTombstoneRetentionTimeInHours'), null())]" + } + }, + "eventHubPropertiesCapture": { + "captureDescription": { + "destination": { + "name": "[parameters('captureDescriptionDestinationName')]", + "properties": { + "archiveNameFormat": "[parameters('captureDescriptionDestinationArchiveNameFormat')]", + "blobContainer": "[parameters('captureDescriptionDestinationBlobContainer')]", + "storageAccountResourceId": "[parameters('captureDescriptionDestinationStorageAccountResourceId')]" + } + }, + "enabled": "[parameters('captureDescriptionEnabled')]", + "encoding": "[parameters('captureDescriptionEncoding')]", + "intervalInSeconds": "[parameters('captureDescriptionIntervalInSeconds')]", + "sizeLimitInBytes": "[parameters('captureDescriptionSizeLimitInBytes')]", + "skipEmptyArchives": "[parameters('captureDescriptionSkipEmptyArchives')]" + } + }, + "builtInRoleNames": { + "Azure Event Hubs Data Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f526a384-b230-433a-b45c-95f59c4a2dec')]", + "Azure Event Hubs Data Receiver": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a638d3c7-ab3a-418d-83e6-5f17a39d4fde')]", + "Azure Event Hubs Data Sender": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '2b629674-e913-4c01-ae53-ef4638d8f975')]", + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", + "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]" + } + }, + "resources": { + "namespace": { + "existing": true, + "type": "Microsoft.EventHub/namespaces", + "apiVersion": "2022-10-01-preview", + "name": "[parameters('namespaceName')]" + }, + "eventHub": { + "type": "Microsoft.EventHub/namespaces/eventhubs", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('name'))]", + "properties": "[if(parameters('captureDescriptionEnabled'), union(variables('eventHubProperties'), variables('eventHubPropertiesCapture')), variables('eventHubProperties'))]", + "dependsOn": [ + "namespace" + ] + }, + "eventHub_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}/eventhubs/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "eventHub" + ] + }, + "eventHub_roleAssignments": { + "copy": { + "name": "eventHub_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.EventHub/namespaces/{0}/eventhubs/{1}', parameters('namespaceName'), parameters('name'))]", + "name": "[guid(resourceId('Microsoft.EventHub/namespaces/eventhubs', parameters('namespaceName'), parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "eventHub" + ] + }, + "eventHub_consumergroups": { + "copy": { + "name": "eventHub_consumergroups", + "count": "[length(parameters('consumergroups'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-ConsumerGroup-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "eventHubName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('consumergroups')[copyIndex()].name]" + }, + "userMetadata": "[if(contains(parameters('consumergroups')[copyIndex()], 'userMetadata'), createObject('value', parameters('consumergroups')[copyIndex()].userMetadata), createObject('value', ''))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "697710281814211564" + }, + "name": "Event Hub Namespace Event Hub Consumer Groups", + "description": "This module deploys an Event Hub Namespace Event Hub Consumer Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.s." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the consumer group." + } + }, + "userMetadata": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. User Metadata is a placeholder to store user-defined string data with maximum length 1024. e.g. it can be used to store descriptive data, such as list of teams and their contact information also user-defined configuration settings can be stored." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/eventhubs/consumergroups", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "userMetadata": "[if(not(empty(parameters('userMetadata'))), parameters('userMetadata'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the consumer group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the consumer group." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs/consumergroups', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the consumer group was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHub" + ] + }, + "eventHub_authorizationRules": { + "copy": { + "name": "eventHub_authorizationRules", + "count": "[length(parameters('authorizationRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-AuthRule-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('namespaceName')]" + }, + "eventHubName": { + "value": "[parameters('name')]" + }, + "name": { + "value": "[parameters('authorizationRules')[copyIndex()].name]" + }, + "rights": "[if(contains(parameters('authorizationRules')[copyIndex()], 'rights'), createObject('value', parameters('authorizationRules')[copyIndex()].rights), createObject('value', createArray()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "16757979367783376523" + }, + "name": "Event Hub Namespace Event Hub Authorization Rules", + "description": "This module deploys an Event Hub Namespace Event Hub Authorization Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "eventHubName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace event hub. Required if the template is used in a standalone deployment." + } + }, + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the authorization rule." + } + }, + "rights": { + "type": "array", + "defaultValue": [], + "allowedValues": [ + "Listen", + "Manage", + "Send" + ], + "metadata": { + "description": "Optional. The rights associated with the rule." + } + } + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/eventhubs/authorizationRules", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}/{2}', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]", + "properties": { + "rights": "[parameters('rights')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the authorization rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the authorization rule." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs/authorizationRules', parameters('namespaceName'), parameters('eventHubName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the authorization rule was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHub" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the event hub." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the event hub." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/eventhubs', parameters('namespaceName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the event hub was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_networkRuleSet": { + "condition": "[or(not(empty(parameters('networkRuleSets'))), not(empty(parameters('privateEndpoints'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-EvhbNamespace-NetworkRuleSet', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "namespaceName": { + "value": "[parameters('name')]" + }, + "publicNetworkAccess": "[if(contains(parameters('networkRuleSets'), 'publicNetworkAccess'), createObject('value', parameters('networkRuleSets').publicNetworkAccess), if(and(not(empty(parameters('privateEndpoints'))), empty(parameters('networkRuleSets'))), createObject('value', 'Disabled'), createObject('value', 'Enabled')))]", + "defaultAction": "[if(contains(parameters('networkRuleSets'), 'defaultAction'), createObject('value', parameters('networkRuleSets').defaultAction), createObject('value', 'Allow'))]", + "trustedServiceAccessEnabled": { + "value": "[tryGet(parameters('networkRuleSets'), 'trustedServiceAccessEnabled')]" + }, + "ipRules": "[if(contains(parameters('networkRuleSets'), 'ipRules'), createObject('value', parameters('networkRuleSets').ipRules), createObject('value', createArray()))]", + "virtualNetworkRules": "[if(contains(parameters('networkRuleSets'), 'virtualNetworkRules'), createObject('value', parameters('networkRuleSets').virtualNetworkRules), createObject('value', createArray()))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "11239292624069957748" + }, + "name": "Event Hub Namespace Network Rule Sets", + "description": "This module deploys an Event Hub Namespace Network Rule Set.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. This determines if traffic is allowed over public network. Default is \"Enabled\". If set to \"Disabled\", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied." + } + }, + "defaultAction": { + "type": "string", + "defaultValue": "Allow", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "Optional. Default Action for Network Rule Set. Default is \"Allow\". It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, it will be set to \"Deny\" if ipRules or virtualNetworkRules are being used." + } + }, + "trustedServiceAccessEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Value that indicates whether Trusted Service Access is enabled or not." + } + }, + "virtualNetworkRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An array of subnet resource ID objects that this Event Hub Namespace is exposed to via Service Endpoints. You can enable the `ignoreMissingVnetServiceEndpoint` if you wish to add this virtual network to Event Hub Namespace but do not have an existing service endpoint. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + }, + "ipRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An array of objects for the public IP ranges you want to allow via the Event Hub Namespace firewall. Supports IPv4 address or CIDR. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + }, + "networkRuleSetName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the network ruleset." + } + } + }, + "variables": { + "copy": [ + { + "name": "networkRules", + "count": "[length(parameters('virtualNetworkRules'))]", + "input": { + "ignoreMissingVnetServiceEndpoint": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'ignoreMissingVnetServiceEndpoint'), parameters('virtualNetworkRules')[copyIndex('networkRules')].ignoreMissingVnetServiceEndpoint, null())]", + "subnet": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'subnetResourceId'), createObject('id', parameters('virtualNetworkRules')[copyIndex('networkRules')].subnetResourceId), null())]" + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/networkRuleSets", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('networkRuleSetName'))]", + "properties": { + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "defaultAction": "[if(equals(parameters('publicNetworkAccess'), 'Disabled'), null(), if(or(not(empty(parameters('ipRules'))), not(empty(parameters('virtualNetworkRules')))), 'Deny', parameters('defaultAction')))]", + "trustedServiceAccessEnabled": "[parameters('trustedServiceAccessEnabled')]", + "ipRules": "[if(equals(parameters('publicNetworkAccess'), 'Disabled'), null(), parameters('ipRules'))]", + "virtualNetworkRules": "[if(equals(parameters('publicNetworkAccess'), 'Disabled'), null(), variables('networkRules'))]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the network rule set." + }, + "value": "[parameters('networkRuleSetName')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the network rule set." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/networkRuleSets', parameters('namespaceName'), parameters('networkRuleSetName'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the network rule set was created in." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "eventHubNamespace" + ] + }, + "eventHubNamespace_privateEndpoints": { + "copy": { + "name": "eventHubNamespace_privateEndpoints", + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-EventHubNamespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex()))]" + }, + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualPrivateLinkServiceConnections'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.EventHub/namespaces', parameters('name')), '/')), coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace'), copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.EventHub/namespaces', parameters('name')), 'groupIds', createArray(coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'service'), 'namespace')), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "subnetResourceId": { + "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" + }, + "enableTelemetry": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'enableTelemetry'), parameters('enableTelemetry'))]" + }, + "location": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'location'), reference(split(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location)]" + }, + "lock": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" + }, + "privateDnsZoneGroupName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" + }, + "privateDnsZoneResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + }, + "roleAssignments": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" + }, + "tags": { + "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'tags'), parameters('tags'))]" + }, + "customDnsConfigs": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customDnsConfigs')]" + }, + "ipConfigurations": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'ipConfigurations')]" + }, + "applicationSecurityGroupResourceIds": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'applicationSecurityGroupResourceIds')]" + }, + "customNetworkInterfaceName": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'customNetworkInterfaceName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.24.24.22086", + "templateHash": "2592884001616184297" + }, + "name": "Private Endpoints", + "description": "This module deploys a Private Endpoint.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + }, + "ipConfigurationsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + } + }, + "nullable": true + }, + "manualPrivateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "privateLinkServiceConnectionsType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "properties": { + "groupIds": { + "type": "array", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } + } + }, + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + } + }, + "nullable": true + }, + "customDnsConfigType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "metadata": { + "description": "Required. Fqdn that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private endpoint resource to create." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the private endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the private endpoint." + } + }, + "ipConfigurations": { + "$ref": "#/definitions/ipConfigurationsType", + "metadata": { + "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." + } + }, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location for all Resources." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "roleAssignments": { + "$ref": "#/definitions/roleAssignmentType", + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." + } + }, + "customDnsConfigs": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "manualPrivateLinkServiceConnections": { + "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + } + }, + "privateLinkServiceConnections": { + "$ref": "#/definitions/privateLinkServiceConnectionsType", + "metadata": { + "description": "Optional. A grouping of information about the connection to the remote resource." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "variables": { + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.0', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "privateEndpoint": { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", + "privateLinkServiceConnections": "[coalesce(parameters('privateLinkServiceConnections'), createArray())]", + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + } + }, + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)))]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, + "privateDNSResourceIds": { + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + }, + "privateEndpointName": { + "value": "[parameters('name')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.24.24.22086", + "templateHash": "9321937464667207030" + }, + "name": "Private Endpoint Private DNS Zone Groups", + "description": "This module deploys a Private Endpoint Private DNS Zone Group.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "privateEndpointName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." + } + }, + "privateDNSResourceIds": { + "type": "array", + "minLength": 1, + "maxLength": 5, + "metadata": { + "description": "Required. Array of private DNS zone resource IDs. A DNS zone group can support up to 5 DNS zones." + } + }, + "name": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the private DNS zone group." + } + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneConfigs", + "count": "[length(parameters('privateDNSResourceIds'))]", + "input": { + "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "properties": { + "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + } + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", + "properties": { + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint DNS zone group." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint DNS zone group." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', parameters('privateEndpointName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint DNS zone group was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "privateEndpoint" + ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." + }, + "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + }, + "name": { + "type": "string", + "metadata": { + "description": "The name of the private endpoint." + }, + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + }, + "groupId": { + "type": "string", + "metadata": { + "description": "The group Id for the private endpoint Group." + }, + "value": "[if(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties.groupIds[0], reference('privateEndpoint').privateLinkServiceConnections[0].properties.groupIds[0])]" + } + } + } + }, + "dependsOn": [ + "eventHubNamespace" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the eventspace." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the eventspace." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group where the namespace is deployed." + }, + "value": "[resourceGroup().name]" + }, + "systemAssignedMIPrincipalId": { + "type": "string", + "metadata": { + "description": "The principal ID of the system assigned identity." + }, + "value": "[coalesce(tryGet(tryGet(reference('eventHubNamespace', '2022-10-01-preview', 'full'), 'identity'), 'principalId'), '')]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('eventHubNamespace', '2022-10-01-preview', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/network-rule-set/README.md b/avm/res/event-hub/namespace/network-rule-set/README.md new file mode 100644 index 0000000000..589fc265f7 --- /dev/null +++ b/avm/res/event-hub/namespace/network-rule-set/README.md @@ -0,0 +1,122 @@ +# Event Hub Namespace Network Rule Sets `[Microsoft.EventHub/namespaces/networkRuleSets]` + +This module deploys an Event Hub Namespace Network Rule Set. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.EventHub/namespaces/networkRuleSets` | [2022-10-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.EventHub/2022-10-01-preview/namespaces/networkRuleSets) | + +## Parameters + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`namespaceName`](#parameter-namespacename) | string | The name of the parent event hub namespace. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`defaultAction`](#parameter-defaultaction) | string | Default Action for Network Rule Set. Default is "Allow". It will not be set if publicNetworkAccess is "Disabled". Otherwise, it will be set to "Deny" if ipRules or virtualNetworkRules are being used. | +| [`ipRules`](#parameter-iprules) | array | An array of objects for the public IP ranges you want to allow via the Event Hub Namespace firewall. Supports IPv4 address or CIDR. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny". | +| [`networkRuleSetName`](#parameter-networkrulesetname) | string | The name of the network ruleset. | +| [`publicNetworkAccess`](#parameter-publicnetworkaccess) | string | This determines if traffic is allowed over public network. Default is "Enabled". If set to "Disabled", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied. | +| [`trustedServiceAccessEnabled`](#parameter-trustedserviceaccessenabled) | bool | Value that indicates whether Trusted Service Access is enabled or not. | +| [`virtualNetworkRules`](#parameter-virtualnetworkrules) | array | An array of subnet resource ID objects that this Event Hub Namespace is exposed to via Service Endpoints. You can enable the `ignoreMissingVnetServiceEndpoint` if you wish to add this virtual network to Event Hub Namespace but do not have an existing service endpoint. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny". | + +### Parameter: `namespaceName` + +The name of the parent event hub namespace. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `defaultAction` + +Default Action for Network Rule Set. Default is "Allow". It will not be set if publicNetworkAccess is "Disabled". Otherwise, it will be set to "Deny" if ipRules or virtualNetworkRules are being used. + +- Required: No +- Type: string +- Default: `'Allow'` +- Allowed: + ```Bicep + [ + 'Allow' + 'Deny' + ] + ``` + +### Parameter: `ipRules` + +An array of objects for the public IP ranges you want to allow via the Event Hub Namespace firewall. Supports IPv4 address or CIDR. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny". + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `networkRuleSetName` + +The name of the network ruleset. + +- Required: No +- Type: string +- Default: `'default'` + +### Parameter: `publicNetworkAccess` + +This determines if traffic is allowed over public network. Default is "Enabled". If set to "Disabled", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied. + +- Required: No +- Type: string +- Default: `'Enabled'` +- Allowed: + ```Bicep + [ + 'Disabled' + 'Enabled' + ] + ``` + +### Parameter: `trustedServiceAccessEnabled` + +Value that indicates whether Trusted Service Access is enabled or not. + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `virtualNetworkRules` + +An array of subnet resource ID objects that this Event Hub Namespace is exposed to via Service Endpoints. You can enable the `ignoreMissingVnetServiceEndpoint` if you wish to add this virtual network to Event Hub Namespace but do not have an existing service endpoint. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny". + +- Required: No +- Type: array +- Default: `[]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the network rule set. | +| `resourceGroupName` | string | The name of the resource group the network rule set was created in. | +| `resourceId` | string | The resource ID of the network rule set. | + +## Cross-referenced modules + +_None_ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/event-hub/namespace/network-rule-set/main.bicep b/avm/res/event-hub/namespace/network-rule-set/main.bicep new file mode 100644 index 0000000000..925095ca39 --- /dev/null +++ b/avm/res/event-hub/namespace/network-rule-set/main.bicep @@ -0,0 +1,64 @@ +metadata name = 'Event Hub Namespace Network Rule Sets' +metadata description = 'This module deploys an Event Hub Namespace Network Rule Set.' +metadata owner = 'Azure/module-maintainers' + +@description('Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment.') +param namespaceName string + +@allowed([ + 'Enabled' + 'Disabled' +]) +@description('Optional. This determines if traffic is allowed over public network. Default is "Enabled". If set to "Disabled", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied.') +param publicNetworkAccess string = 'Enabled' + +@allowed([ + 'Allow' + 'Deny' +]) +@description('Optional. Default Action for Network Rule Set. Default is "Allow". It will not be set if publicNetworkAccess is "Disabled". Otherwise, it will be set to "Deny" if ipRules or virtualNetworkRules are being used.') +param defaultAction string = 'Allow' + +@description('Optional. Value that indicates whether Trusted Service Access is enabled or not.') +param trustedServiceAccessEnabled bool = true + +@description('Optional. An array of subnet resource ID objects that this Event Hub Namespace is exposed to via Service Endpoints. You can enable the `ignoreMissingVnetServiceEndpoint` if you wish to add this virtual network to Event Hub Namespace but do not have an existing service endpoint. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny".') +param virtualNetworkRules array = [] + +@description('Optional. An array of objects for the public IP ranges you want to allow via the Event Hub Namespace firewall. Supports IPv4 address or CIDR. It will not be set if publicNetworkAccess is "Disabled". Otherwise, when used, defaultAction will be set to "Deny".') +param ipRules array = [] + +@description('Optional. The name of the network ruleset.') + param networkRuleSetName string = 'default' + +var networkRules = [for (virtualNetworkRule, index) in virtualNetworkRules: { + ignoreMissingVnetServiceEndpoint: contains(virtualNetworkRule, 'ignoreMissingVnetServiceEndpoint') ? virtualNetworkRule.ignoreMissingVnetServiceEndpoint : null + subnet: contains(virtualNetworkRule, 'subnetResourceId') ? { + id: virtualNetworkRule.subnetResourceId + } : null +}] + +resource namespace 'Microsoft.EventHub/namespaces@2022-10-01-preview' existing = { + name: namespaceName +} + +resource networkRuleSet 'Microsoft.EventHub/namespaces/networkRuleSets@2022-10-01-preview' = { + name: networkRuleSetName + parent: namespace + properties: { + publicNetworkAccess: publicNetworkAccess + defaultAction: publicNetworkAccess == 'Disabled' ? null : (!empty(ipRules) || !empty(virtualNetworkRules) ? 'Deny' : defaultAction) + trustedServiceAccessEnabled: trustedServiceAccessEnabled + ipRules: publicNetworkAccess == 'Disabled' ? null : ipRules + virtualNetworkRules: publicNetworkAccess == 'Disabled' ? null : networkRules + } +} + +@description('The name of the network rule set.') +output name string = networkRuleSet.name + +@description('The resource ID of the network rule set.') +output resourceId string = networkRuleSet.id + +@description('The name of the resource group the network rule set was created in.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/event-hub/namespace/network-rule-set/main.json b/avm/res/event-hub/namespace/network-rule-set/main.json new file mode 100644 index 0000000000..923c335e93 --- /dev/null +++ b/avm/res/event-hub/namespace/network-rule-set/main.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.25.53.49325", + "templateHash": "11239292624069957748" + }, + "name": "Event Hub Namespace Network Rule Sets", + "description": "This module deploys an Event Hub Namespace Network Rule Set.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "namespaceName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent event hub namespace. Required if the template is used in a standalone deployment." + } + }, + "publicNetworkAccess": { + "type": "string", + "defaultValue": "Enabled", + "allowedValues": [ + "Enabled", + "Disabled" + ], + "metadata": { + "description": "Optional. This determines if traffic is allowed over public network. Default is \"Enabled\". If set to \"Disabled\", traffic to this namespace will be restricted over Private Endpoints only and network rules will not be applied." + } + }, + "defaultAction": { + "type": "string", + "defaultValue": "Allow", + "allowedValues": [ + "Allow", + "Deny" + ], + "metadata": { + "description": "Optional. Default Action for Network Rule Set. Default is \"Allow\". It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, it will be set to \"Deny\" if ipRules or virtualNetworkRules are being used." + } + }, + "trustedServiceAccessEnabled": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Value that indicates whether Trusted Service Access is enabled or not." + } + }, + "virtualNetworkRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An array of subnet resource ID objects that this Event Hub Namespace is exposed to via Service Endpoints. You can enable the `ignoreMissingVnetServiceEndpoint` if you wish to add this virtual network to Event Hub Namespace but do not have an existing service endpoint. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + }, + "ipRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An array of objects for the public IP ranges you want to allow via the Event Hub Namespace firewall. Supports IPv4 address or CIDR. It will not be set if publicNetworkAccess is \"Disabled\". Otherwise, when used, defaultAction will be set to \"Deny\"." + } + }, + "networkRuleSetName": { + "type": "string", + "defaultValue": "default", + "metadata": { + "description": "Optional. The name of the network ruleset." + } + } + }, + "variables": { + "copy": [ + { + "name": "networkRules", + "count": "[length(parameters('virtualNetworkRules'))]", + "input": { + "ignoreMissingVnetServiceEndpoint": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'ignoreMissingVnetServiceEndpoint'), parameters('virtualNetworkRules')[copyIndex('networkRules')].ignoreMissingVnetServiceEndpoint, null())]", + "subnet": "[if(contains(parameters('virtualNetworkRules')[copyIndex('networkRules')], 'subnetResourceId'), createObject('id', parameters('virtualNetworkRules')[copyIndex('networkRules')].subnetResourceId), null())]" + } + } + ] + }, + "resources": [ + { + "type": "Microsoft.EventHub/namespaces/networkRuleSets", + "apiVersion": "2022-10-01-preview", + "name": "[format('{0}/{1}', parameters('namespaceName'), parameters('networkRuleSetName'))]", + "properties": { + "publicNetworkAccess": "[parameters('publicNetworkAccess')]", + "defaultAction": "[if(equals(parameters('publicNetworkAccess'), 'Disabled'), null(), if(or(not(empty(parameters('ipRules'))), not(empty(parameters('virtualNetworkRules')))), 'Deny', parameters('defaultAction')))]", + "trustedServiceAccessEnabled": "[parameters('trustedServiceAccessEnabled')]", + "ipRules": "[if(equals(parameters('publicNetworkAccess'), 'Disabled'), null(), parameters('ipRules'))]", + "virtualNetworkRules": "[if(equals(parameters('publicNetworkAccess'), 'Disabled'), null(), variables('networkRules'))]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the network rule set." + }, + "value": "[parameters('networkRuleSetName')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the network rule set." + }, + "value": "[resourceId('Microsoft.EventHub/namespaces/networkRuleSets', parameters('namespaceName'), parameters('networkRuleSetName'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the network rule set was created in." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..b6a55d3ace --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,46 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-eventhub.namespaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'ehnmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + } +}] diff --git a/avm/res/event-hub/namespace/tests/e2e/encr/dependencies.bicep b/avm/res/event-hub/namespace/tests/e2e/encr/dependencies.bicep new file mode 100644 index 0000000000..dab158fd15 --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/encr/dependencies.bicep @@ -0,0 +1,90 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Required. The name of the Key Vault to create.') +param keyVaultName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +var addressPrefix = '10.0.0.0/16' + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource keyVault 'Microsoft.KeyVault/vaults@2022-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: 'standard' + } + tenantId: tenant().tenantId + enablePurgeProtection: true // Required by event hub namespace + softDeleteRetentionInDays: 7 + enabledForTemplateDeployment: true + enabledForDiskEncryption: true + enabledForDeployment: true + enableRbacAuthorization: true + accessPolicies: [] + } + + resource key 'keys@2022-07-01' = { + name: 'keyEncryptionKey' + properties: { + kty: 'RSA' + } + } +} + +resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault::key.id}-${location}-${managedIdentity.id}-Key-Reader-RoleAssignment') + scope: keyVault::key + properties: { + principalId: managedIdentity.properties.principalId + // Key Vault Crypto User + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') + principalType: 'ServicePrincipal' + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Key Vault.') +output keyVaultResourceId string = keyVault.id + +@description('The name of the created encryption key.') +output keyName string = keyVault::key.name + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id diff --git a/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep new file mode 100644 index 0000000000..d4296b83d8 --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/encr/main.test.bicep @@ -0,0 +1,74 @@ +targetScope = 'subscription' + +metadata name = 'Using encryption with Customer-Managed-Key' +metadata description = 'This instance deploys the module using Customer-Managed-Keys using a User-Assigned Identity to access the Customer-Managed-Key secret.' + + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-eventhub.namespaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'ehnenc' + +@description('Generated. Used as a basis for unique resource names.') +param baseTime string = utcNow('u') + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + // Adding base time to make the name unique as purge protection must be enabled (but may not be longer than 24 characters total) + keyVaultName: 'dep-${namePrefix}-kv-${serviceShort}-${substring(uniqueString(baseTime), 0, 3)}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // +module testDeployment '../../../main.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + publicNetworkAccess: 'SecuredByPerimeter' + skuName: 'Premium' + managedIdentities: { + systemAssigned: false + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + customerManagedKey: { + keyName: nestedDependencies.outputs.keyName + keyVaultResourceId: nestedDependencies.outputs.keyVaultResourceId + userAssignedIdentityResourceId: nestedDependencies.outputs.managedIdentityResourceId + } + requireInfrastructureEncryption: true + } +} diff --git a/avm/res/event-hub/namespace/tests/e2e/max/dependencies.bicep b/avm/res/event-hub/namespace/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..6bc7e40df9 --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/max/dependencies.bicep @@ -0,0 +1,83 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Managed Identity to create.') +param managedIdentityName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + serviceEndpoints: [ + { + service: 'Microsoft.EventHub' + } + ] + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.servicebus.windows.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = { + name: managedIdentityName + location: location +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The principal ID of the created Managed Identity.') +output managedIdentityPrincipalId string = managedIdentity.properties.principalId + +@description('The resource ID of the created Managed Identity.') +output managedIdentityResourceId string = managedIdentity.id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id diff --git a/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..4433a3e1a0 --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/max/main.test.bicep @@ -0,0 +1,236 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-eventhub.namespaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'ehnmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + zoneRedundant: true + skuName: 'Standard' + skuCapacity: 2 + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + eventhubs: [ + { + name: '${namePrefix}-az-evh-x-001' + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + } + { + name: '${namePrefix}-az-evh-x-002' + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: 'eventhub' + captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + captureDescriptionEnabled: true + captureDescriptionEncoding: 'Avro' + captureDescriptionIntervalInSeconds: 300 + captureDescriptionSizeLimitInBytes: 314572800 + captureDescriptionSkipEmptyArchives: true + consumergroups: [ + { + name: 'custom' + userMetadata: 'customMetadata' + } + ] + messageRetentionInDays: 1 + partitionCount: 2 + roleAssignments: [ + { + roleDefinitionIdOrName: 'Reader' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + status: 'Active' + retentionDescriptionCleanupPolicy: 'Delete' + retentionDescriptionRetentionTimeInHours: 3 + } + { + name: '${namePrefix}-az-evh-x-003' + retentionDescriptionCleanupPolicy: 'Compact' + retentionDescriptionTombstoneRetentionTimeInHours: 24 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + networkRuleSets: { + defaultAction: 'Deny' + ipRules: [ + { + action: 'Allow' + ipMask: '10.10.10.10' + } + ] + trustedServiceAccessEnabled: false + publicNetworkAccess: 'Disabled' + virtualNetworkRules: [ + { + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + service: 'namespace' + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + roleAssignments: [ + { + roleDefinitionIdOrName: 'Owner' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: 'b24988ac-6180-42a0-ab88-20f7382dd24c' + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + { + roleDefinitionIdOrName: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + principalId: nestedDependencies.outputs.managedIdentityPrincipalId + principalType: 'ServicePrincipal' + } + ] + managedIdentities: { + systemAssigned: true + userAssignedResourceIds: [ + nestedDependencies.outputs.managedIdentityResourceId + ] + } + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + kafkaEnabled: true + disableLocalAuth: true + isAutoInflateEnabled: true + minimumTlsVersion: '1.2' + maximumThroughputUnits: 4 + publicNetworkAccess: 'Disabled' + } +}] diff --git a/avm/res/event-hub/namespace/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/event-hub/namespace/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..ad5c60a774 --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,69 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Storage Account to create.') +param storageAccountName string + +var addressPrefix = '10.0.0.0/16' + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + serviceEndpoints: [ + { + service: 'Microsoft.EventHub' + } + ] + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.servicebus.windows.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = { + name: storageAccountName + location: location + sku: { + name: 'Standard_LRS' + } + kind: 'StorageV2' +} + +@description('The resource ID of the created Virtual Network Subnet.') +output subnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id + +@description('The resource ID of the created Storage Account.') +output storageAccountResourceId string = storageAccount.id diff --git a/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..607e156738 --- /dev/null +++ b/avm/res/event-hub/namespace/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,192 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-eventhub.namespaces-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'ehnwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + storageAccountName: 'dep${namePrefix}sa${serviceShort}' + } +} + +// Diagnostics +// =========== +module diagnosticDependencies '../../../../../../utilities/e2e-template-assets/templates/diagnostic.dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-diagnosticDependencies' + params: { + storageAccountName: 'dep${namePrefix}diasa${serviceShort}03' + logAnalyticsWorkspaceName: 'dep-${namePrefix}-law-${serviceShort}' + eventHubNamespaceEventHubName: 'dep-${namePrefix}-evh-${serviceShort}01' + eventHubNamespaceName: 'dep-${namePrefix}-evhns-${serviceShort}01' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + name: '${namePrefix}${serviceShort}001' + location: resourceLocation + zoneRedundant: true + skuName: 'Standard' + skuCapacity: 2 + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + diagnosticSettings: [ + { + name: 'customSetting' + metricCategories: [ + { + category: 'AllMetrics' + } + ] + eventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName + eventHubAuthorizationRuleResourceId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId + storageAccountResourceId: diagnosticDependencies.outputs.storageAccountResourceId + workspaceResourceId: diagnosticDependencies.outputs.logAnalyticsWorkspaceResourceId + } + ] + eventhubs: [ + { + name: '${namePrefix}-az-evh-x-001' + } + { + name: '${namePrefix}-az-evh-x-002' + authorizationRules: [ + { + name: 'RootManageSharedAccessKey' + rights: [ + 'Listen' + 'Manage' + 'Send' + ] + } + { + name: 'SendListenAccess' + rights: [ + 'Listen' + 'Send' + ] + } + ] + captureDescriptionDestinationArchiveNameFormat: '{Namespace}/{EventHub}/{PartitionId}/{Year}/{Month}/{Day}/{Hour}/{Minute}/{Second}' + captureDescriptionDestinationBlobContainer: 'eventhub' + captureDescriptionDestinationName: 'EventHubArchive.AzureBlockBlob' + captureDescriptionDestinationStorageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId + captureDescriptionEnabled: true + captureDescriptionEncoding: 'Avro' + captureDescriptionIntervalInSeconds: 300 + captureDescriptionSizeLimitInBytes: 314572800 + captureDescriptionSkipEmptyArchives: true + consumergroups: [ + { + name: 'custom' + userMetadata: 'customMetadata' + } + ] + messageRetentionInDays: 1 + partitionCount: 2 + status: 'Active' + retentionDescriptionCleanupPolicy: 'Delete' + retentionDescriptionRetentionTimeInHours: 3 + } + { + name: '${namePrefix}-az-evh-x-003' + retentionDescriptionCleanupPolicy: 'Compact' + retentionDescriptionTombstoneRetentionTimeInHours: 24 + } + ] + networkRuleSets: { + defaultAction: 'Deny' + ipRules: [ + { + action: 'Allow' + ipMask: '10.10.10.10' + } + ] + trustedServiceAccessEnabled: false + virtualNetworkRules: [ + { + ignoreMissingVnetServiceEndpoint: true + subnetResourceId: nestedDependencies.outputs.subnetResourceId + } + ] + } + privateEndpoints: [ + { + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] + subnetResourceId: nestedDependencies.outputs.subnetResourceId + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + ] + kafkaEnabled: true + disableLocalAuth: true + isAutoInflateEnabled: true + minimumTlsVersion: '1.2' + maximumThroughputUnits: 4 + publicNetworkAccess: 'Disabled' + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] diff --git a/avm/res/event-hub/namespace/version.json b/avm/res/event-hub/namespace/version.json new file mode 100644 index 0000000000..83083db694 --- /dev/null +++ b/avm/res/event-hub/namespace/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} \ No newline at end of file