From 8e5729753f9a887bda5c000e63eec8e3086abeb8 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Wed, 4 Sep 2024 08:20:21 +0200 Subject: [PATCH] feat: Update private endpoints to the newest specs - batch 2 (#3163) ## Description Private endpoints - Update to newest specs ## Pipeline Reference | Pipeline | | -------- | | [![avm.res.insights.private-link-scope](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.insights.private-link-scope.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.insights.private-link-scope.yml) | | [![avm.res.key-vault.vault](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.key-vault.vault.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.key-vault.vault.yml) | | [![avm.res.kusto.cluster](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.kusto.cluster.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.kusto.cluster.yml) | | [![avm.res.network.application-gateway](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.application-gateway.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.network.application-gateway.yml) | | [![avm.res.purview.account](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.purview.account.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.purview.account.yml) | | [![avm.res.recovery-services.vault](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.recovery-services.vault.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.recovery-services.vault.yml) | | [![avm.res.relay.namespace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.relay.namespace.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.relay.namespace.yml) | | [![avm.res.service-bus.namespace](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.service-bus.namespace.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.service-bus.namespace.yml) | | [![avm.res.signal-r-service.signal-r](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.signal-r-service.signal-r.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.signal-r-service.signal-r.yml) | | [![avm.res.signal-r-service.web-pub-sub](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.signal-r-service.web-pub-sub.yml/badge.svg?branch=users%2Fkrbar%2FpeUpdate2&event=workflow_dispatch)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.signal-r-service.web-pub-sub.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [x] Breaking changes and I have bumped the MAJOR version in `version.json`. - [ ] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/res/insights/private-link-scope/README.md | 105 ++- .../insights/private-link-scope/main.bicep | 33 +- avm/res/insights/private-link-scope/main.json | 277 ++++-- .../tests/e2e/max/main.test.bicep | 10 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- .../insights/private-link-scope/version.json | 2 +- avm/res/key-vault/vault/README.md | 125 ++- avm/res/key-vault/vault/main.bicep | 33 +- avm/res/key-vault/vault/main.json | 277 ++++-- .../vault/tests/e2e/max/dependencies.bicep | 2 +- .../vault/tests/e2e/max/main.test.bicep | 20 +- .../tests/e2e/waf-aligned/dependencies.bicep | 2 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- avm/res/key-vault/vault/version.json | 2 +- avm/res/kusto/cluster/README.md | 234 ++++- avm/res/kusto/cluster/main.bicep | 63 +- avm/res/kusto/cluster/main.json | 316 +++++-- .../cluster/tests/e2e/pe/dependencies.bicep | 68 ++ .../cluster/tests/e2e/pe/main.test.bicep | 92 ++ avm/res/kusto/cluster/version.json | 2 +- avm/res/network/application-gateway/README.md | 105 ++- .../network/application-gateway/main.bicep | 33 +- avm/res/network/application-gateway/main.json | 277 ++++-- .../tests/e2e/defaults/main.test.bicep | 1 - .../tests/e2e/max/main.test.bicep | 10 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- .../network/application-gateway/version.json | 2 +- avm/res/purview/account/README.md | 537 ++++++++--- avm/res/purview/account/main.bicep | 108 ++- avm/res/purview/account/main.json | 864 ++++++++++++++---- .../account/tests/e2e/max/main.test.bicep | 70 +- .../tests/e2e/waf-aligned/main.test.bicep | 50 +- avm/res/purview/account/version.json | 2 +- avm/res/recovery-services/vault/README.md | 101 +- avm/res/recovery-services/vault/main.bicep | 33 +- avm/res/recovery-services/vault/main.json | 210 ++++- .../vault/tests/e2e/max/main.test.bicep | 10 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- avm/res/recovery-services/vault/version.json | 2 +- avm/res/relay/namespace/README.md | 121 ++- avm/res/relay/namespace/main.bicep | 33 +- avm/res/relay/namespace/main.json | 210 ++++- .../namespace/tests/e2e/max/main.test.bicep | 20 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- avm/res/relay/namespace/version.json | 2 +- avm/res/service-bus/namespace/README.md | 121 ++- avm/res/service-bus/namespace/main.bicep | 33 +- avm/res/service-bus/namespace/main.json | 210 ++++- .../namespace/tests/e2e/max/main.test.bicep | 20 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- avm/res/service-bus/namespace/version.json | 2 +- avm/res/signal-r-service/signal-r/README.md | 121 ++- avm/res/signal-r-service/signal-r/main.bicep | 33 +- avm/res/signal-r-service/signal-r/main.json | 210 ++++- .../signal-r/tests/e2e/max/main.test.bicep | 20 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- .../signal-r-service/signal-r/version.json | 2 +- .../signal-r-service/web-pub-sub/README.md | 121 ++- .../signal-r-service/web-pub-sub/main.bicep | 33 +- .../signal-r-service/web-pub-sub/main.json | 210 ++++- .../web-pub-sub/tests/e2e/max/main.test.bicep | 20 +- .../tests/e2e/waf-aligned/main.test.bicep | 10 +- .../signal-r-service/web-pub-sub/version.json | 2 +- 63 files changed, 4460 insertions(+), 1242 deletions(-) create mode 100644 avm/res/kusto/cluster/tests/e2e/pe/dependencies.bicep create mode 100644 avm/res/kusto/cluster/tests/e2e/pe/main.test.bicep diff --git a/avm/res/insights/private-link-scope/README.md b/avm/res/insights/private-link-scope/README.md index d6e1a8d04a..cbed0f5ba9 100644 --- a/avm/res/insights/private-link-scope/README.md +++ b/avm/res/insights/private-link-scope/README.md @@ -19,8 +19,8 @@ This module deploys an Azure Monitor Private Link Scope. | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `microsoft.insights/privateLinkScopes` | [2021-07-01-preview](https://learn.microsoft.com/en-us/azure/templates/microsoft.insights/2021-07-01-preview/privateLinkScopes) | | `Microsoft.Insights/privateLinkScopes/scopedResources` | [2021-07-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-07-01-preview/privateLinkScopes/scopedResources) | -| `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) | +| `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | ## Usage examples @@ -208,9 +208,13 @@ module privateLinkScope 'br/public:avm/res/insights/private-link-scope: } ] name: 'pe-' - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } roleAssignments: [ { principalId: '' @@ -394,9 +398,13 @@ module privateLinkScope 'br/public:avm/res/insights/private-link-scope: } ], "name": "pe-", - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "roleAssignments": [ { "principalId": "", @@ -567,9 +575,13 @@ module privateLinkScope 'br/public:avm/res/insights/private-link-scope: } ] name: 'pe-' - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -708,9 +720,13 @@ module privateLinkScope 'br/public:avm/res/insights/private-link-scope: } ], "name": "pe-", - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "", "tags": { "Environment": "Non-Prod", @@ -943,8 +959,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -1128,19 +1143,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -1406,6 +1466,7 @@ Resource tags. | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the private link scope. | +| `privateEndpoints` | array | The private endpoints of the private link scope. | | `resourceGroupName` | string | The resource group the private link scope was deployed into. | | `resourceId` | string | The resource ID of the private link scope. | @@ -1415,7 +1476,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.4.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/insights/private-link-scope/main.bicep b/avm/res/insights/private-link-scope/main.bicep index e926990853..50534b0383 100644 --- a/avm/res/insights/private-link-scope/main.bicep +++ b/avm/res/insights/private-link-scope/main.bicep @@ -154,7 +154,7 @@ resource privateLinkScope_lock 'Microsoft.Authorization/locks@2020-05-01' = if ( scope: privateLinkScope } -module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ +module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-privateLinkScope-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -195,8 +195,7 @@ module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endp 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -235,6 +234,17 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = privateLinkScope.location +@description('The private endpoints of the private link scope.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: privateLinkScope_privateEndpoints[i].outputs.name + resourceId: privateLinkScope_privateEndpoints[i].outputs.resourceId + groupId: privateLinkScope_privateEndpoints[i].outputs.groupId + customDnsConfig: privateLinkScope_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: privateLinkScope_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -289,11 +299,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/insights/private-link-scope/main.json b/avm/res/insights/private-link-scope/main.json index fdb7f2a158..c1efbd235d 100644 --- a/avm/res/insights/private-link-scope/main.json +++ b/avm/res/insights/private-link-scope/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "2401315355721407155" + "templateHash": "9210191494689145931" }, "name": "Azure Monitor Private Link Scopes", "description": "This module deploys an Azure Monitor Private Link Scope.", @@ -150,21 +150,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -678,11 +701,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -710,19 +730,47 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4120048060064073955" + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { "type": "object", "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, "roleDefinitionIdOrName": { "type": "string", "metadata": { @@ -826,13 +874,13 @@ "groupId": { "type": "string", "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "memberName": { "type": "string", "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "privateIPAddress": { @@ -866,8 +914,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -907,8 +958,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -956,6 +1010,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -991,18 +1068,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1058,6 +1128,13 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", @@ -1075,8 +1152,8 @@ "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1094,7 +1171,7 @@ }, "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -1135,27 +1212,27 @@ "privateEndpoint_roleAssignments": { "copy": { "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), 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)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "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')]" + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ "privateEndpoint" ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1166,28 +1243,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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": "11244630631275470040" + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1195,12 +1296,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1214,27 +1318,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -1292,14 +1405,28 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" }, "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])]" + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" } } } @@ -1337,6 +1464,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('privateLinkScope', '2021-07-01-preview', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the private link scope." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep b/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep index 68deb2d0a6..25c575033e 100644 --- a/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep +++ b/avm/res/insights/private-link-scope/tests/e2e/max/main.test.bicep @@ -78,9 +78,13 @@ module testDeployment '../../../main.bicep' = [ name: 'pe-${namePrefix}' customNetworkInterfaceName: 'nic-pe-${namePrefix}' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep b/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep index c92cf66a1d..5a537cd3fe 100644 --- a/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/insights/private-link-scope/tests/e2e/waf-aligned/main.test.bicep @@ -65,9 +65,13 @@ module testDeployment '../../../main.bicep' = [ name: 'pe-${namePrefix}' customNetworkInterfaceName: 'nic-pe-${namePrefix}' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/avm/res/insights/private-link-scope/version.json b/avm/res/insights/private-link-scope/version.json index 3f863a2bec..a8eda31021 100644 --- a/avm/res/insights/private-link-scope/version.json +++ b/avm/res/insights/private-link-scope/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.4", + "version": "0.5", "pathFilters": [ "./main.json" ] diff --git a/avm/res/key-vault/vault/README.md b/avm/res/key-vault/vault/README.md index 08b4fc5a1e..f6d19e1046 100644 --- a/avm/res/key-vault/vault/README.md +++ b/avm/res/key-vault/vault/README.md @@ -22,8 +22,8 @@ This module deploys a Key Vault. | `Microsoft.KeyVault/vaults/accessPolicies` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/accessPolicies) | | `Microsoft.KeyVault/vaults/keys` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/keys) | | `Microsoft.KeyVault/vaults/secrets` | [2022-07-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.KeyVault/2022-07-01/vaults/secrets) | -| `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) | +| `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | ## Usage examples @@ -369,9 +369,13 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } } ] - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } roleAssignments: [ { principalId: '' @@ -392,9 +396,13 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -625,9 +633,13 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } } ], - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "roleAssignments": [ { "principalId": "", @@ -648,9 +660,13 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -914,9 +930,13 @@ module vault 'br/public:avm/res/key-vault/vault:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'vault' subnetResourceId: '' } @@ -1028,9 +1048,13 @@ module vault 'br/public:avm/res/key-vault/vault:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "vault", "subnetResourceId": "" } @@ -1937,8 +1961,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -2122,19 +2145,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -2595,6 +2663,7 @@ Resource tags. | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the key vault. | +| `privateEndpoints` | array | The private endpoints of the key vault. | | `resourceGroupName` | string | The name of the resource group the key vault was created in. | | `resourceId` | string | The resource ID of the key vault. | | `uri` | string | The URI of the key vault. | @@ -2605,7 +2674,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.4.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/key-vault/vault/main.bicep b/avm/res/key-vault/vault/main.bicep index 4e6ab84d43..b804b867e7 100644 --- a/avm/res/key-vault/vault/main.bicep +++ b/avm/res/key-vault/vault/main.bicep @@ -301,7 +301,7 @@ module keyVault_keys 'key/main.bicep' = [ } ] -module keyVault_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ +module keyVault_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-keyVault-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -342,8 +342,7 @@ module keyVault_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -388,6 +387,17 @@ output uri string = keyVault.properties.vaultUri @description('The location the resource was deployed into.') output location string = keyVault.location +@description('The private endpoints of the key vault.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: keyVault_privateEndpoints[i].outputs.name + resourceId: keyVault_privateEndpoints[i].outputs.resourceId + groupId: keyVault_privateEndpoints[i].outputs.groupId + customDnsConfig: keyVault_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: keyVault_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // ================ // // Definitions // // ================ // @@ -478,11 +488,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: 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('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: string? + + @description('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/key-vault/vault/main.json b/avm/res/key-vault/vault/main.json index cdcd99757f..15f25dc8bb 100644 --- a/avm/res/key-vault/vault/main.json +++ b/avm/res/key-vault/vault/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "4127506616814902143" + "templateHash": "535497364453680203" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -245,21 +245,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -2096,11 +2119,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -2128,19 +2148,47 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4120048060064073955" + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { "type": "object", "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, "roleDefinitionIdOrName": { "type": "string", "metadata": { @@ -2244,13 +2292,13 @@ "groupId": { "type": "string", "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "memberName": { "type": "string", "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "privateIPAddress": { @@ -2284,8 +2332,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -2325,8 +2376,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -2374,6 +2428,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -2409,18 +2486,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -2476,6 +2546,13 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", @@ -2493,8 +2570,8 @@ "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2512,7 +2589,7 @@ }, "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -2553,27 +2630,27 @@ "privateEndpoint_roleAssignments": { "copy": { "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), 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)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "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')]" + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ "privateEndpoint" ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -2584,28 +2661,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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": "11244630631275470040" + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -2613,12 +2714,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -2632,27 +2736,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -2710,14 +2823,28 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" }, "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])]" + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" } } } @@ -2762,6 +2889,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('keyVault', '2022-07-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the key vault." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('keyVault_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/key-vault/vault/tests/e2e/max/dependencies.bicep b/avm/res/key-vault/vault/tests/e2e/max/dependencies.bicep index f433490224..6c3754d07f 100644 --- a/avm/res/key-vault/vault/tests/e2e/max/dependencies.bicep +++ b/avm/res/key-vault/vault/tests/e2e/max/dependencies.bicep @@ -62,4 +62,4 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id output managedIdentityPrincipalId string = managedIdentity.properties.principalId @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep index 9aa9d3e7b1..08693fdd86 100644 --- a/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep +++ b/avm/res/key-vault/vault/tests/e2e/max/main.test.bicep @@ -192,9 +192,13 @@ module testDeployment '../../../main.bicep' = [ } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' @@ -236,9 +240,13 @@ module testDeployment '../../../main.bicep' = [ ] } { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] diff --git a/avm/res/key-vault/vault/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/key-vault/vault/tests/e2e/waf-aligned/dependencies.bicep index f433490224..6c3754d07f 100644 --- a/avm/res/key-vault/vault/tests/e2e/waf-aligned/dependencies.bicep +++ b/avm/res/key-vault/vault/tests/e2e/waf-aligned/dependencies.bicep @@ -62,4 +62,4 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id output managedIdentityPrincipalId string = managedIdentity.properties.principalId @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep b/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep index f75788795d..88763ac590 100644 --- a/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/key-vault/vault/tests/e2e/waf-aligned/main.test.bicep @@ -122,9 +122,13 @@ module testDeployment '../../../main.bicep' = [ } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } service: 'vault' subnetResourceId: nestedDependencies.outputs.subnetResourceId } diff --git a/avm/res/key-vault/vault/version.json b/avm/res/key-vault/vault/version.json index 7e1d3f4157..0f81d22abc 100644 --- a/avm/res/key-vault/vault/version.json +++ b/avm/res/key-vault/vault/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.7", + "version": "0.8", "pathFilters": [ "./main.json" ] diff --git a/avm/res/kusto/cluster/README.md b/avm/res/kusto/cluster/README.md index 17048e468c..6f79b14c35 100644 --- a/avm/res/kusto/cluster/README.md +++ b/avm/res/kusto/cluster/README.md @@ -20,8 +20,8 @@ This module deploys a Kusto Cluster. | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Kusto/clusters` | [2023-08-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Kusto/2023-08-15/clusters) | | `Microsoft.Kusto/clusters/principalAssignments` | [2023-08-15](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Kusto/2023-08-15/clusters/principalAssignments) | -| `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) | +| `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | ## Usage examples @@ -33,7 +33,8 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) -- [WAF-aligned](#example-3-waf-aligned) +- [Private endpoint-enabled deployment](#example-3-private-endpoint-enabled-deployment) +- [WAF-aligned](#example-4-waf-aligned) ### Example 1: _Using only defaults_ @@ -301,7 +302,129 @@ module cluster 'br/public:avm/res/kusto/cluster:' = {

-### Example 3: _WAF-aligned_ +### Example 3: _Private endpoint-enabled deployment_ + +This instance deploys the module with private endpoints. + + +

+ +via Bicep module + +```bicep +module cluster 'br/public:avm/res/kusto/cluster:' = { + name: 'clusterDeployment' + params: { + // Required parameters + name: 'akcpe0001' + sku: 'Standard_E2ads_v5' + // Non-required parameters + enablePublicNetworkAccess: false + location: '' + privateEndpoints: [ + { + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } + service: 'cluster' + subnetResourceId: '' + } + { + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } + service: 'cluster' + subnetResourceId: '' + } + ] + publicIPType: 'IPv4' + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +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": "akcpe0001" + }, + "sku": { + "value": "Standard_E2ads_v5" + }, + // Non-required parameters + "enablePublicNetworkAccess": { + "value": false + }, + "location": { + "value": "" + }, + "privateEndpoints": { + "value": [ + { + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, + "service": "cluster", + "subnetResourceId": "" + }, + { + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, + "service": "cluster", + "subnetResourceId": "" + } + ] + }, + "publicIPType": { + "value": "IPv4" + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 4: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -974,7 +1097,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`service`](#parameter-privateendpointsservice) | string | The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file". | | [`subnetResourceId`](#parameter-privateendpointssubnetresourceid) | string | Resource ID of the subnet where the endpoint needs to be created. | **Optional parameters** @@ -986,19 +1109,20 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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 | Manual PrivateLink Service Connections. | +| [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | +| [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | | [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | ### Parameter: `privateEndpoints.service` -The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob". +The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file". - Required: Yes - Type: string @@ -1028,19 +1152,19 @@ Custom DNS configurations. | 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. | +| [`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. +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. +A list of private IP addresses of the private endpoint. - Required: Yes - Type: array @@ -1093,7 +1217,7 @@ Properties of private endpoint IP configurations. | :-- | :-- | :-- | | [`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. | +| [`privateIPAddress`](#parameter-privateendpointsipconfigurationspropertiesprivateipaddress) | string | A private IP address obtained from the private endpoint's subnet. | ### Parameter: `privateEndpoints.ipConfigurations.properties.groupId` @@ -1111,14 +1235,14 @@ The member name of a group obtained from the remote resource that this private e ### Parameter: `privateEndpoints.ipConfigurations.properties.privateIPAddress` -A private ip address obtained from the private endpoint's subnet. +A private IP address obtained from the private endpoint's subnet. - Required: Yes - Type: string ### Parameter: `privateEndpoints.isManualConnection` -Manual PrivateLink Service Connections. +If Manual Private Link Connection is required. - Required: No - Type: bool @@ -1180,19 +1304,78 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.privateLinkServiceConnectionName` + +The name of the private link connection to create. + +- Required: No +- Type: string + +### Parameter: `privateEndpoints.resourceGroupName` + +Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. + +- Required: No +- Type: string ### Parameter: `privateEndpoints.roleAssignments` @@ -1511,9 +1694,10 @@ The resource ID of the subnet to which to deploy the Kusto Cluster. | Output | Type | Description | | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | -| `name` | string | The name of the resource. | -| `resourceGroupName` | string | The resource group the resource was deployed into. | -| `resourceId` | string | The resource id of the resource. | +| `name` | string | The name of the kusto cluster. | +| `privateEndpoints` | array | The private endpoints of the kusto cluster. | +| `resourceGroupName` | string | The resource group the kusto cluster was deployed into. | +| `resourceId` | string | The resource id of the kusto cluster. | ## Cross-referenced modules @@ -1521,7 +1705,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.4.0` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/kusto/cluster/main.bicep b/avm/res/kusto/cluster/main.bicep index 345e2b7317..2a9802eb5e 100644 --- a/avm/res/kusto/cluster/main.bicep +++ b/avm/res/kusto/cluster/main.bicep @@ -301,12 +301,14 @@ module kustoCluster_principalAssignments 'principal-assignment/main.bicep' = [ } ] -module kustoCluster_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ +@batchSize(1) +module kustoCluster_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-KustoCluster-PrivateEndpoint-${index}' + name: '${uniqueString(deployment().name, location)}-kustoCluster-PrivateEndpoint-${index}' + scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') params: { name: privateEndpoint.?name ?? 'pep-${last(split(kustoCluster.id, '/'))}-${privateEndpoint.service}-${index}' - privateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections != true + privateLinkServiceConnections: privateEndpoint.?isManualConnection != true ? [ { name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(kustoCluster.id, '/'))}-${privateEndpoint.service}-${index}' @@ -319,7 +321,7 @@ module kustoCluster_privateEndpoints 'br/public:avm/res/network/private-endpoint } ] : null - manualPrivateLinkServiceConnections: privateEndpoint.?manualPrivateLinkServiceConnections == true + manualPrivateLinkServiceConnections: privateEndpoint.?isManualConnection == true ? [ { name: privateEndpoint.?privateLinkServiceConnectionName ?? '${last(split(kustoCluster.id, '/'))}-${privateEndpoint.service}-${index}' @@ -341,8 +343,7 @@ module kustoCluster_privateEndpoints 'br/public:avm/res/network/private-endpoint 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -357,18 +358,29 @@ module kustoCluster_privateEndpoints 'br/public:avm/res/network/private-endpoint // Outputs // // ============ // -@description('The resource group the resource was deployed into.') +@description('The resource group the kusto cluster was deployed into.') output resourceGroupName string = resourceGroup().name -@description('The resource id of the resource.') +@description('The resource id of the kusto cluster.') output resourceId string = kustoCluster.id -@description('The name of the resource.') +@description('The name of the kusto cluster.') output name string = kustoCluster.name @description('The location the resource was deployed into.') output location string = kustoCluster.location +@description('The private endpoints of the kusto cluster.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: kustoCluster_privateEndpoints[i].outputs.name + resourceId: kustoCluster_privateEndpoints[i].outputs.resourceId + groupId: kustoCluster_privateEndpoints[i].outputs.groupId + customDnsConfig: kustoCluster_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: kustoCluster_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -478,19 +490,31 @@ type privateEndpointType = { @description('Optional. The location to deploy the private endpoint to.') location: string? - @description('Required. The service (sub-) type to deploy the private endpoint for. For example "vault" or "blob".') + @description('Optional. The name of the private link connection to create.') + privateLinkServiceConnectionName: string? + + @description('Required. The subresource to deploy the private endpoint for. For example "blob", "table", "queue" or "file".') 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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? - @description('Optional. Manual PrivateLink Service Connections.') + @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.') @@ -499,10 +523,10 @@ type privateEndpointType = { @description('Optional. Custom DNS configurations.') customDnsConfigs: { - @description('Required. Fqdn that resolves to private endpoint ip address.') + @description('Required. Fqdn that resolves to private endpoint IP address.') fqdn: string? - @description('Required. A list of private ip addresses of the private endpoint.') + @description('Required. A list of private IP addresses of the private endpoint.') ipAddresses: string[] }[]? @@ -519,7 +543,7 @@ type privateEndpointType = { @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.') + @description('Required. A private IP address obtained from the private endpoint\'s subnet.') privateIPAddress: string } }[]? @@ -541,6 +565,9 @@ type privateEndpointType = { @description('Optional. Enable/Disable usage telemetry for module.') enableTelemetry: bool? + + @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') + resourceGroupName: string? }[]? type roleAssignmentType = { diff --git a/avm/res/kusto/cluster/main.json b/avm/res/kusto/cluster/main.json index 21f5cc3e7e..8135431606 100644 --- a/avm/res/kusto/cluster/main.json +++ b/avm/res/kusto/cluster/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "5568505662059755727" + "templateHash": "4366309935211132094" }, "name": "Kusto Cluster", "description": "This module deploys a Kusto Cluster.", @@ -283,40 +283,70 @@ "description": "Optional. The location to deploy the private endpoint to." } }, - "service": { + "privateLinkServiceConnectionName": { "type": "string", + "nullable": true, "metadata": { - "description": "Required. The service (sub-) type to deploy the private endpoint for. For example \"vault\" or \"blob\"." + "description": "Optional. The name of the private link connection to create." } }, - "subnetResourceId": { + "service": { "type": "string", "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + "description": "Required. The subresource to deploy the private endpoint for. For example \"blob\", \"table\", \"queue\" or \"file\"." } }, - "privateDnsZoneGroupName": { + "subnetResourceId": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group to create if privateDnsZoneResourceIds were provided." + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." } }, - "privateDnsZoneResourceIds": { - "type": "array", - "items": { - "type": "string" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { "type": "bool", "nullable": true, "metadata": { - "description": "Optional. Manual PrivateLink Service Connections." + "description": "Optional. If Manual Private Link Connection is required." } }, "manualConnectionRequestMessage": { @@ -336,7 +366,7 @@ "type": "string", "nullable": true, "metadata": { - "description": "Required. Fqdn that resolves to private endpoint ip address." + "description": "Required. Fqdn that resolves to private endpoint IP address." } }, "ipAddresses": { @@ -345,7 +375,7 @@ "type": "string" }, "metadata": { - "description": "Required. A list of private ip addresses of the private endpoint." + "description": "Required. A list of private IP addresses of the private endpoint." } } } @@ -384,7 +414,7 @@ "privateIPAddress": { "type": "string", "metadata": { - "description": "Required. A private ip address obtained from the private endpoint's subnet." + "description": "Required. A private IP address obtained from the private endpoint's subnet." } } }, @@ -441,6 +471,13 @@ "metadata": { "description": "Optional. Enable/Disable usage telemetry for module." } + }, + "resourceGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource." + } } } }, @@ -1129,11 +1166,14 @@ "kustoCluster_privateEndpoints": { "copy": { "name": "kustoCluster_privateEndpoints", - "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]" + "count": "[length(coalesce(parameters('privateEndpoints'), createArray()))]", + "mode": "serial", + "batchSize": 1 }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-KustoCluster-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-kustoCluster-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -1143,8 +1183,8 @@ "name": { "value": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'name'), format('pep-{0}-{1}-{2}', last(split(resourceId('Microsoft.Kusto/clusters', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, 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.Kusto/clusters', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Kusto/clusters', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), 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.Kusto/clusters', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Kusto/clusters', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", + "privateLinkServiceConnections": "[if(not(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true())), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Kusto/clusters', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Kusto/clusters', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service))))), createObject('value', null()))]", + "manualPrivateLinkServiceConnections": "[if(equals(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'isManualConnection'), true()), createObject('value', createArray(createObject('name', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateLinkServiceConnectionName'), format('{0}-{1}-{2}', last(split(resourceId('Microsoft.Kusto/clusters', parameters('name')), '/')), coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service, copyIndex())), 'properties', createObject('privateLinkServiceId', resourceId('Microsoft.Kusto/clusters', parameters('name')), 'groupIds', createArray(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].service), 'requestMessage', coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'manualConnectionRequestMessage'), 'Manual approval required.'))))), createObject('value', null()))]", "subnetResourceId": { "value": "[coalesce(parameters('privateEndpoints'), createArray())[copyIndex()].subnetResourceId]" }, @@ -1157,11 +1197,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -1189,19 +1226,47 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.24.24.22086", - "templateHash": "2592884001616184297" + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { "type": "object", "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, "roleDefinitionIdOrName": { "type": "string", "metadata": { @@ -1305,13 +1370,13 @@ "groupId": { "type": "string", "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "memberName": { "type": "string", "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "privateIPAddress": { @@ -1345,8 +1410,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -1386,8 +1454,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -1435,6 +1506,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -1470,18 +1564,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1537,6 +1624,13 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", @@ -1554,8 +1648,8 @@ "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))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1573,7 +1667,7 @@ }, "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -1614,27 +1708,27 @@ "privateEndpoint_roleAssignments": { "copy": { "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), 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)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "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')]" + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ "privateEndpoint" ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1645,28 +1739,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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": "9321937464667207030" + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1674,12 +1792,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1693,27 +1814,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -1771,14 +1901,28 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" }, "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])]" + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" } } } @@ -1792,21 +1936,21 @@ "resourceGroupName": { "type": "string", "metadata": { - "description": "The resource group the resource was deployed into." + "description": "The resource group the kusto cluster was deployed into." }, "value": "[resourceGroup().name]" }, "resourceId": { "type": "string", "metadata": { - "description": "The resource id of the resource." + "description": "The resource id of the kusto cluster." }, "value": "[resourceId('Microsoft.Kusto/clusters', parameters('name'))]" }, "name": { "type": "string", "metadata": { - "description": "The name of the resource." + "description": "The name of the kusto cluster." }, "value": "[parameters('name')]" }, @@ -1816,6 +1960,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('kustoCluster', '2023-08-15', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the kusto cluster." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('kustoCluster_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('kustoCluster_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('kustoCluster_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('kustoCluster_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('kustoCluster_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/kusto/cluster/tests/e2e/pe/dependencies.bicep b/avm/res/kusto/cluster/tests/e2e/pe/dependencies.bicep new file mode 100644 index 0000000000..1b34a4ac45 --- /dev/null +++ b/avm/res/kusto/cluster/tests/e2e/pe/dependencies.bicep @@ -0,0 +1,68 @@ +@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 + +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, 24, 0) + serviceEndpoints: [ + { + service: 'Microsoft.KeyVault' + } + ] + } + } + { + name: 'peTestSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 24, 1) + serviceEndpoints: [ + { + service: 'Microsoft.KeyVault' + } + ] + } + } + ] + } +} + +resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { + name: 'privatelink.digitaltwins.azure.net' + location: 'global' + + resource virtualNetworkLinks 'virtualNetworkLinks@2020-06-01' = { + name: '${virtualNetwork.name}-vnetlink' + location: 'global' + properties: { + virtualNetwork: { + id: virtualNetwork.id + } + registrationEnabled: false + } + } +} + +@description('The resource ID of the created Virtual Network Subnet.') +output defaultSubnetResourceId string = virtualNetwork.properties.subnets[0].id + +@description('The resource ID of the created Virtual Network Subnet.') +output pepTestSubnetResourceId string = virtualNetwork.properties.subnets[1].id + +@description('The resource ID of the created Private DNS Zone.') +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/avm/res/kusto/cluster/tests/e2e/pe/main.test.bicep b/avm/res/kusto/cluster/tests/e2e/pe/main.test.bicep new file mode 100644 index 0000000000..bdb035d2c8 --- /dev/null +++ b/avm/res/kusto/cluster/tests/e2e/pe/main.test.bicep @@ -0,0 +1,92 @@ +targetScope = 'subscription' + +metadata name = 'Private endpoint-enabled deployment' +metadata description = 'This instance deploys the module with private endpoints.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-kusto.clusters-${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 = 'akcpe' + +@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: { + location: resourceLocation + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + } +} + +// ============== // +// 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}0001' + location: resourceLocation + sku: 'Standard_E2ads_v5' + enablePublicNetworkAccess: false + publicIPType: 'IPv4' + privateEndpoints: [ + { + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } + subnetResourceId: nestedDependencies.outputs.defaultSubnetResourceId + service: 'cluster' + } + { + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } + subnetResourceId: nestedDependencies.outputs.pepTestSubnetResourceId + service: 'cluster' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + dependsOn: [ + nestedDependencies + ] + } +] diff --git a/avm/res/kusto/cluster/version.json b/avm/res/kusto/cluster/version.json index 729ac87673..76049e1c4a 100644 --- a/avm/res/kusto/cluster/version.json +++ b/avm/res/kusto/cluster/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.2", + "version": "0.3", "pathFilters": [ "./main.json" ] diff --git a/avm/res/network/application-gateway/README.md b/avm/res/network/application-gateway/README.md index eb63406f99..bcfdeb7ef5 100644 --- a/avm/res/network/application-gateway/README.md +++ b/avm/res/network/application-gateway/README.md @@ -19,8 +19,8 @@ This module deploys a Network Application Gateway. | `Microsoft.Authorization/roleAssignments` | [2022-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2022-04-01/roleAssignments) | | `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | | `Microsoft.Network/applicationGateways` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/applicationGateways) | -| `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) | +| `Microsoft.Network/privateEndpoints` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints) | +| `Microsoft.Network/privateEndpoints/privateDnsZoneGroups` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/privateEndpoints/privateDnsZoneGroups) | ## Usage examples @@ -463,9 +463,13 @@ module applicationGateway 'br/public:avm/res/network/application-gateway:' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'public' subnetResourceId: '' tags: { @@ -950,9 +954,13 @@ module applicationGateway 'br/public:avm/res/network/application-gateway:" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "public", "subnetResourceId": "", "tags": { @@ -1438,9 +1446,13 @@ module applicationGateway 'br/public:avm/res/network/application-gateway:' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'public' subnetResourceId: '' tags: { @@ -1877,9 +1889,13 @@ module applicationGateway 'br/public:avm/res/network/application-gateway:" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "public", "subnetResourceId": "", "tags": { @@ -2556,8 +2572,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -2747,19 +2762,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -3220,6 +3280,7 @@ A list of availability zones denoting where the resource needs to come from. | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the application gateway. | +| `privateEndpoints` | array | The private endpoints of the application gateway. | | `resourceGroupName` | string | The resource group the application gateway was deployed into. | | `resourceId` | string | The resource ID of the application gateway. | @@ -3229,7 +3290,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.4.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/network/application-gateway/main.bicep b/avm/res/network/application-gateway/main.bicep index 2a78297afa..636fa01efb 100644 --- a/avm/res/network/application-gateway/main.bicep +++ b/avm/res/network/application-gateway/main.bicep @@ -382,7 +382,7 @@ resource applicationGateway_diagnosticSettings 'Microsoft.Insights/diagnosticSet } ] -module applicationGateway_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.1' = [ +module applicationGateway_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-applicationGateway-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -423,8 +423,7 @@ module applicationGateway_privateEndpoints 'br/public:avm/res/network/private-en 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -467,6 +466,17 @@ output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') output location string = applicationGateway.location +@description('The private endpoints of the application gateway.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: applicationGateway_privateEndpoints[i].outputs.name + resourceId: applicationGateway_privateEndpoints[i].outputs.resourceId + groupId: applicationGateway_privateEndpoints[i].outputs.groupId + customDnsConfig: applicationGateway_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: applicationGateway_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -526,11 +536,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/network/application-gateway/main.json b/avm/res/network/application-gateway/main.json index e5fdb4c6e6..7876f434e6 100644 --- a/avm/res/network/application-gateway/main.json +++ b/avm/res/network/application-gateway/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "8779879628045972124" + "templateHash": "10337247586212656300" }, "name": "Network Application Gateways", "description": "This module deploys a Network Application Gateway.", @@ -164,21 +164,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -987,11 +1010,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -1019,19 +1039,47 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.25.53.49325", - "templateHash": "4120048060064073955" + "version": "0.29.47.4906", + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { "type": "object", "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." + } + }, "roleDefinitionIdOrName": { "type": "string", "metadata": { @@ -1135,13 +1183,13 @@ "groupId": { "type": "string", "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "memberName": { "type": "string", "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string." } }, "privateIPAddress": { @@ -1175,8 +1223,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -1216,8 +1267,11 @@ "properties": { "groupIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. If used with private link service connection, this property must be defined as empty string array `[]`." } }, "privateLinkServiceId": { @@ -1265,6 +1319,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -1300,18 +1377,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1367,6 +1437,13 @@ } }, "variables": { + "copy": [ + { + "name": "formattedRoleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]", + "input": "[union(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')], createObject('roleDefinitionId', coalesce(tryGet(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName), if(contains(coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, '/providers/Microsoft.Authorization/roleDefinitions/'), coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName, subscriptionResourceId('Microsoft.Authorization/roleDefinitions', coalesce(parameters('roleAssignments'), createArray())[copyIndex('formattedRoleAssignments')].roleDefinitionIdOrName)))))]" + } + ], "builtInRoleNames": { "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", @@ -1384,8 +1461,8 @@ "avmTelemetry": { "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", - "apiVersion": "2023-07-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.4.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "apiVersion": "2024-03-01", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1403,7 +1480,7 @@ }, "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", @@ -1444,27 +1521,27 @@ "privateEndpoint_roleAssignments": { "copy": { "name": "privateEndpoint_roleAssignments", - "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + "count": "[length(coalesce(variables('formattedRoleAssignments'), 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)]", + "name": "[coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'name'), guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId, coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId))]", "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')]" + "roleDefinitionId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].roleDefinitionId]", + "principalId": "[coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(variables('formattedRoleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ "privateEndpoint" ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1475,28 +1552,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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": "11244630631275470040" + "version": "0.29.47.4906", + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1504,12 +1605,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1523,27 +1627,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-04-01", + "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -1601,14 +1714,28 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" + }, + "customDnsConfig": { + "$ref": "#/definitions/customDnsConfigType", + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + }, + "value": "[reference('privateEndpoint').customDnsConfigs]" + }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" }, "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])]" + "value": "[if(and(not(empty(reference('privateEndpoint').manualPrivateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').manualPrivateLinkServiceConnections[0].properties, 'groupIds', 0), ''), if(and(not(empty(reference('privateEndpoint').privateLinkServiceConnections)), greater(length(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds')), 0)), coalesce(tryGet(reference('privateEndpoint').privateLinkServiceConnections[0].properties, 'groupIds', 0), ''), ''))]" } } } @@ -1646,6 +1773,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('applicationGateway', '2023-04-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the application gateway." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('applicationGateway_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('applicationGateway_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('applicationGateway_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('applicationGateway_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('applicationGateway_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/network/application-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/application-gateway/tests/e2e/defaults/main.test.bicep index 6225ac703b..8bb4990db1 100644 --- a/avm/res/network/application-gateway/tests/e2e/defaults/main.test.bicep +++ b/avm/res/network/application-gateway/tests/e2e/defaults/main.test.bicep @@ -9,7 +9,6 @@ metadata description = 'This instance deploys the module with the minimum set of @description('Optional. The name of the resource group to deploy for testing purposes.') @maxLength(90) -// e.g., for a module 'network/private-endpoint' you could use 'dep-dev-network.privateendpoints-${serviceShort}-rg' param resourceGroupName string = 'dep-${namePrefix}-network.applicationgateway-${serviceShort}-rg' @description('Optional. The location to deploy resources to.') diff --git a/avm/res/network/application-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/application-gateway/tests/e2e/max/main.test.bicep index cad487791d..9dfbbced50 100644 --- a/avm/res/network/application-gateway/tests/e2e/max/main.test.bicep +++ b/avm/res/network/application-gateway/tests/e2e/max/main.test.bicep @@ -169,9 +169,13 @@ module testDeployment '../../../main.bicep' = [ ] privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } service: 'public' subnetResourceId: nestedDependencies.outputs.privateLinkSubnetResourceId tags: { diff --git a/avm/res/network/application-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/application-gateway/tests/e2e/waf-aligned/main.test.bicep index 2082ab2b6a..a7eb20e1fc 100644 --- a/avm/res/network/application-gateway/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/network/application-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -165,9 +165,13 @@ module testDeployment '../../../main.bicep' = [ ] privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } service: 'public' subnetResourceId: nestedDependencies.outputs.privateLinkSubnetResourceId tags: { diff --git a/avm/res/network/application-gateway/version.json b/avm/res/network/application-gateway/version.json index c177b1bb58..3f863a2bec 100644 --- a/avm/res/network/application-gateway/version.json +++ b/avm/res/network/application-gateway/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/res/purview/account/README.md b/avm/res/purview/account/README.md index 71150ebc19..ce0a389913 100644 --- a/avm/res/purview/account/README.md +++ b/avm/res/purview/account/README.md @@ -105,9 +105,13 @@ module account 'br/public:avm/res/purview/account:' = { // Non-required parameters accountPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'account' subnetResourceId: '' tags: { @@ -133,9 +137,13 @@ module account 'br/public:avm/res/purview/account:' = { ] eventHubPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'namespace' subnetResourceId: '' tags: { @@ -158,9 +166,13 @@ module account 'br/public:avm/res/purview/account:' = { managedResourceGroupName: 'pvamax001-managed-rg' portalPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'portal' subnetResourceId: '' tags: { @@ -170,9 +182,13 @@ module account 'br/public:avm/res/purview/account:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -198,9 +214,13 @@ module account 'br/public:avm/res/purview/account:' = { ] storageBlobPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'blob' subnetResourceId: '' tags: { @@ -212,9 +232,13 @@ module account 'br/public:avm/res/purview/account:' = { ] storageQueuePrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'queue' subnetResourceId: '' tags: { @@ -224,9 +248,13 @@ module account 'br/public:avm/res/purview/account:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -259,9 +287,13 @@ module account 'br/public:avm/res/purview/account:' = { "accountPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "account", "subnetResourceId": "", "tags": { @@ -291,9 +323,13 @@ module account 'br/public:avm/res/purview/account:' = { "eventHubPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "namespace", "subnetResourceId": "", "tags": { @@ -326,9 +362,13 @@ module account 'br/public:avm/res/purview/account:' = { "portalPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "portal", "subnetResourceId": "", "tags": { @@ -338,9 +378,13 @@ module account 'br/public:avm/res/purview/account:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -372,9 +416,13 @@ module account 'br/public:avm/res/purview/account:' = { "storageBlobPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "blob", "subnetResourceId": "", "tags": { @@ -388,9 +436,13 @@ module account 'br/public:avm/res/purview/account:' = { "storageQueuePrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "queue", "subnetResourceId": "", "tags": { @@ -400,9 +452,13 @@ module account 'br/public:avm/res/purview/account:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -439,9 +495,13 @@ module account 'br/public:avm/res/purview/account:' = { // Non-required parameters accountPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'account' subnetResourceId: '' } @@ -456,9 +516,13 @@ module account 'br/public:avm/res/purview/account:' = { ] eventHubPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'namespace' subnetResourceId: '' } @@ -467,9 +531,13 @@ module account 'br/public:avm/res/purview/account:' = { managedResourceGroupName: 'pvawaf001-managed-rg' portalPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'portal' subnetResourceId: '' } @@ -477,18 +545,26 @@ module account 'br/public:avm/res/purview/account:' = { publicNetworkAccess: 'Disabled' storageBlobPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'blob' subnetResourceId: '' } ] storageQueuePrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'queue' subnetResourceId: '' } @@ -522,9 +598,13 @@ module account 'br/public:avm/res/purview/account:' = { "accountPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "account", "subnetResourceId": "" } @@ -543,9 +623,13 @@ module account 'br/public:avm/res/purview/account:' = { "eventHubPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "namespace", "subnetResourceId": "" } @@ -560,9 +644,13 @@ module account 'br/public:avm/res/purview/account:' = { "portalPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "portal", "subnetResourceId": "" } @@ -574,9 +662,13 @@ module account 'br/public:avm/res/purview/account:' = { "storageBlobPrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "blob", "subnetResourceId": "" } @@ -585,9 +677,13 @@ module account 'br/public:avm/res/purview/account:' = { "storageQueuePrivateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "queue", "subnetResourceId": "" } @@ -669,8 +765,7 @@ Configuration details for Purview Account private endpoints. For security reason | [`lock`](#parameter-accountprivateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-accountprivateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | | [`name`](#parameter-accountprivateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroupName`](#parameter-accountprivateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | -| [`privateDnsZoneResourceIds`](#parameter-accountprivateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroup`](#parameter-accountprivateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-accountprivateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-accountprivateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-accountprivateendpointsroleassignments) | array | Array of role assignments to create. | @@ -854,19 +949,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `accountPrivateEndpoints.privateDnsZoneGroupName` +### Parameter: `accountPrivateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-accountprivateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-accountprivateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `accountPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-accountprivateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-accountprivateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `accountPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `accountPrivateEndpoints.privateDnsZoneResourceIds` +### Parameter: `accountPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `accountPrivateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `accountPrivateEndpoints.privateLinkServiceConnectionName` @@ -1174,8 +1314,7 @@ Configuration details for Purview Managed Event Hub namespace private endpoints. | [`lock`](#parameter-eventhubprivateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-eventhubprivateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | | [`name`](#parameter-eventhubprivateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroupName`](#parameter-eventhubprivateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | -| [`privateDnsZoneResourceIds`](#parameter-eventhubprivateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroup`](#parameter-eventhubprivateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-eventhubprivateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-eventhubprivateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-eventhubprivateendpointsroleassignments) | array | Array of role assignments to create. | @@ -1359,19 +1498,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `eventHubPrivateEndpoints.privateDnsZoneGroupName` +### Parameter: `eventHubPrivateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-eventhubprivateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-eventhubprivateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `eventHubPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-eventhubprivateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-eventhubprivateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `eventHubPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `eventHubPrivateEndpoints.privateDnsZoneResourceIds` +### Parameter: `eventHubPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `eventHubPrivateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `eventHubPrivateEndpoints.privateLinkServiceConnectionName` @@ -1597,8 +1781,7 @@ Configuration details for Purview Portal private endpoints. For security reasons | [`lock`](#parameter-portalprivateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-portalprivateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | | [`name`](#parameter-portalprivateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroupName`](#parameter-portalprivateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | -| [`privateDnsZoneResourceIds`](#parameter-portalprivateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroup`](#parameter-portalprivateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-portalprivateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-portalprivateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-portalprivateendpointsroleassignments) | array | Array of role assignments to create. | @@ -1782,19 +1965,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `portalPrivateEndpoints.privateDnsZoneGroupName` +### Parameter: `portalPrivateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-portalprivateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-portalprivateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `portalPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-portalprivateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-portalprivateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `portalPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `portalPrivateEndpoints.privateDnsZoneResourceIds` +### Parameter: `portalPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `portalPrivateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `portalPrivateEndpoints.privateLinkServiceConnectionName` @@ -2061,8 +2289,7 @@ Configuration details for Purview Managed Storage Account blob private endpoints | [`lock`](#parameter-storageblobprivateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-storageblobprivateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | | [`name`](#parameter-storageblobprivateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroupName`](#parameter-storageblobprivateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | -| [`privateDnsZoneResourceIds`](#parameter-storageblobprivateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroup`](#parameter-storageblobprivateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-storageblobprivateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-storageblobprivateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-storageblobprivateendpointsroleassignments) | array | Array of role assignments to create. | @@ -2246,19 +2473,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneGroupName` +### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneGroup` + +The private DNS zone group to configure for the private endpoint. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-storageblobprivateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-storageblobprivateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-storageblobprivateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-storageblobprivateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes +- Type: string + +### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The name of the private DNS zone group config. - Required: No - Type: string -### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneResourceIds` +### Parameter: `storageBlobPrivateEndpoints.privateDnsZoneGroup.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the Private DNS Zone Group. - Required: No -- Type: array +- Type: string ### Parameter: `storageBlobPrivateEndpoints.privateLinkServiceConnectionName` @@ -2412,8 +2684,7 @@ Configuration details for Purview Managed Storage Account queue private endpoint | [`lock`](#parameter-storagequeueprivateendpointslock) | object | Specify the type of lock. | | [`manualConnectionRequestMessage`](#parameter-storagequeueprivateendpointsmanualconnectionrequestmessage) | string | A message passed to the owner of the remote resource with the manual connection request. | | [`name`](#parameter-storagequeueprivateendpointsname) | string | The name of the private endpoint. | -| [`privateDnsZoneGroupName`](#parameter-storagequeueprivateendpointsprivatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | -| [`privateDnsZoneResourceIds`](#parameter-storagequeueprivateendpointsprivatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroup`](#parameter-storagequeueprivateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-storagequeueprivateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-storagequeueprivateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-storagequeueprivateendpointsroleassignments) | array | Array of role assignments to create. | @@ -2597,19 +2868,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneGroupName` +### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-storagequeueprivateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-storagequeueprivateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-storagequeueprivateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-storagequeueprivateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneResourceIds` +### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `storageQueuePrivateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `storageQueuePrivateEndpoints.privateLinkServiceConnectionName` @@ -2748,14 +3064,19 @@ Tags of the resource. | Output | Type | Description | | :-- | :-- | :-- | +| `accountPrivateEndpoints` | array | The private endpoints of the Purview Account. | +| `eventHubPrivateEndpoints` | array | The private endpoints of the managed Event Hub Namespace. | | `location` | string | The location the resource was deployed into. | | `managedEventHubId` | string | The resource ID of the managed Event Hub Namespace. | | `managedResourceGroupId` | string | The resource ID of the managed resource group. | | `managedResourceGroupName` | string | The name of the managed resource group. | | `managedStorageAccountId` | string | The resource ID of the managed storage account. | | `name` | string | The name of the Purview Account. | +| `portalPrivateEndpoints` | array | The private endpoints of the Purview Account Portal. | | `resourceGroupName` | string | The resource group the Purview Account was deployed into. | | `resourceId` | string | The resource ID of the Purview Account. | +| `storageBlobPrivateEndpoints` | array | The private endpoints of the managed storage account blob service. | +| `storageQueuePrivateEndpoints` | array | The private endpoints of the managed storage account queue service. | | `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | ## Cross-referenced modules @@ -2764,7 +3085,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.6.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/purview/account/main.bicep b/avm/res/purview/account/main.bicep index d665e01bfa..392942cbf6 100644 --- a/avm/res/purview/account/main.bicep +++ b/avm/res/purview/account/main.bicep @@ -165,9 +165,9 @@ resource account_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021- } ] -module account_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module account_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (accountPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Account-PrivateEndpoint-${index}' + name: '${uniqueString(deployment().name, location)}-account-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'account'}-${index}' @@ -206,8 +206,7 @@ module account_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6. 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -218,9 +217,9 @@ module account_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6. } ] -module portal_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module portal_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (portalPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Portal-PrivateEndpoint-${index}' + name: '${uniqueString(deployment().name, location)}-portal-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'portal'}-${index}' @@ -259,8 +258,7 @@ module portal_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -271,9 +269,9 @@ module portal_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1 } ] -module blob_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module blob_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (storageBlobPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Storage-Blob-PrivateEndpoint-${index}' + name: '${uniqueString(deployment().name, location)}-blob-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'blob'}-${index}' @@ -312,8 +310,7 @@ module blob_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -324,9 +321,9 @@ module blob_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' } ] -module queue_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module queue_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (storageQueuePrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Storage-Queue-PrivateEndpoint-${index}' + name: '${uniqueString(deployment().name, location)}-queue-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'queue'}-${index}' @@ -365,8 +362,7 @@ module queue_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -377,9 +373,9 @@ module queue_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' } ] -module eventHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module eventHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (eventHubPrivateEndpoints ?? []): { - name: '${uniqueString(deployment().name, location)}-Eventhub-Namespace-PrivateEndpoint-${index}' + name: '${uniqueString(deployment().name, location)}-eventHub-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') params: { name: privateEndpoint.?name ?? 'pep-${last(split(account.id, '/'))}-${privateEndpoint.?service ?? 'namespace'}-${index}' @@ -418,8 +414,7 @@ module eventHub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -473,6 +468,61 @@ output managedEventHubId string = account.properties.managedResources.eventHubNa @description('The principal ID of the system assigned identity.') output systemAssignedMIPrincipalId string = account.?identity.?principalId ?? '' +@description('The private endpoints of the Purview Account.') +output accountPrivateEndpoints array = [ + for (pe, i) in (!empty(accountPrivateEndpoints) ? array(accountPrivateEndpoints) : []): { + name: account_privateEndpoints[i].outputs.name + resourceId: account_privateEndpoints[i].outputs.resourceId + groupId: account_privateEndpoints[i].outputs.groupId + customDnsConfig: account_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: account_privateEndpoints[i].outputs.networkInterfaceIds + } +] + +@description('The private endpoints of the Purview Account Portal.') +output portalPrivateEndpoints array = [ + for (pe, i) in (!empty(portalPrivateEndpoints) ? array(portalPrivateEndpoints) : []): { + name: portal_privateEndpoints[i].outputs.name + resourceId: portal_privateEndpoints[i].outputs.resourceId + groupId: portal_privateEndpoints[i].outputs.groupId + customDnsConfig: portal_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: portal_privateEndpoints[i].outputs.networkInterfaceIds + } +] + +@description('The private endpoints of the managed storage account blob service.') +output storageBlobPrivateEndpoints array = [ + for (pe, i) in (!empty(storageBlobPrivateEndpoints) ? array(storageBlobPrivateEndpoints) : []): { + name: blob_privateEndpoints[i].outputs.name + resourceId: blob_privateEndpoints[i].outputs.resourceId + groupId: blob_privateEndpoints[i].outputs.groupId + customDnsConfig: blob_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: blob_privateEndpoints[i].outputs.networkInterfaceIds + } +] + +@description('The private endpoints of the managed storage account queue service.') +output storageQueuePrivateEndpoints array = [ + for (pe, i) in (!empty(storageQueuePrivateEndpoints) ? array(storageQueuePrivateEndpoints) : []): { + name: queue_privateEndpoints[i].outputs.name + resourceId: queue_privateEndpoints[i].outputs.resourceId + groupId: queue_privateEndpoints[i].outputs.groupId + customDnsConfig: queue_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: queue_privateEndpoints[i].outputs.networkInterfaceIds + } +] + +@description('The private endpoints of the managed Event Hub Namespace.') +output eventHubPrivateEndpoints array = [ + for (pe, i) in (!empty(eventHubPrivateEndpoints) ? array(eventHubPrivateEndpoints) : []): { + name: eventHub_privateEndpoints[i].outputs.name + resourceId: eventHub_privateEndpoints[i].outputs.resourceId + groupId: eventHub_privateEndpoints[i].outputs.groupId + customDnsConfig: eventHub_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: eventHub_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -570,18 +620,26 @@ type privateEndpointType = { @description('Optional. The name of the private link connection to create.') privateLinkServiceConnectionName: string? - // Variant 1: A default service can be assumed (i.e., for services that only have one private endpoint type) @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/purview/account/main.json b/avm/res/purview/account/main.json index d7e0b0c0ad..f4cf2712e1 100644 --- a/avm/res/purview/account/main.json +++ b/avm/res/purview/account/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "8913927126760967534" + "templateHash": "15039051778035234501" }, "name": "Purview Accounts", "description": "This module deploys a Purview Account.", @@ -285,21 +285,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -687,7 +710,7 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Account-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-account-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "resourceGroup": "[coalesce(tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { @@ -712,11 +735,8 @@ "lock": { "value": "[coalesce(tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" - }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('accountPrivateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -745,13 +765,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -1003,6 +1044,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -1038,18 +1102,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1130,7 +1187,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1209,7 +1266,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1220,28 +1277,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1249,12 +1330,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1268,27 +1352,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -1355,6 +1448,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -1376,7 +1476,7 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Portal-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-portal-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "resourceGroup": "[coalesce(tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { @@ -1401,11 +1501,8 @@ "lock": { "value": "[coalesce(tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" - }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('portalPrivateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -1434,13 +1531,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -1692,6 +1810,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -1727,18 +1868,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1819,7 +1953,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1898,7 +2032,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1909,28 +2043,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1938,12 +2096,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1957,27 +2118,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -2044,6 +2214,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -2065,7 +2242,7 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Storage-Blob-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-blob-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "resourceGroup": "[coalesce(tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { @@ -2090,11 +2267,8 @@ "lock": { "value": "[coalesce(tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" - }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('storageBlobPrivateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -2123,13 +2297,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -2381,6 +2576,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -2416,18 +2634,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -2508,7 +2719,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2587,7 +2798,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -2598,28 +2809,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -2627,12 +2862,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -2646,27 +2884,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -2733,6 +2980,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -2754,7 +3008,7 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Storage-Queue-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-queue-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "resourceGroup": "[coalesce(tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { @@ -2779,11 +3033,8 @@ "lock": { "value": "[coalesce(tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" - }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('storageQueuePrivateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -2812,13 +3063,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -3070,6 +3342,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -3105,18 +3400,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -3197,7 +3485,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -3276,7 +3564,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -3287,28 +3575,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -3316,12 +3628,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -3335,27 +3650,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -3422,6 +3746,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -3443,7 +3774,7 @@ }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-Eventhub-Namespace-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", + "name": "[format('{0}-eventHub-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", "resourceGroup": "[coalesce(tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { @@ -3468,11 +3799,8 @@ "lock": { "value": "[coalesce(tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'lock'), parameters('lock'))]" }, - "privateDnsZoneGroupName": { - "value": "[tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroupName')]" - }, - "privateDnsZoneResourceIds": { - "value": "[tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneResourceIds')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('eventHubPrivateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -3501,13 +3829,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -3759,6 +4108,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -3794,18 +4166,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -3886,7 +4251,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -3965,7 +4330,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -3976,28 +4341,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -4005,12 +4394,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -4024,27 +4416,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -4111,6 +4512,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -4189,6 +4597,86 @@ "description": "The principal ID of the system assigned identity." }, "value": "[coalesce(tryGet(tryGet(reference('account', '2021-07-01', 'full'), 'identity'), 'principalId'), '')]" + }, + "accountPrivateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the Purview Account." + }, + "copy": { + "count": "[length(if(not(empty(parameters('accountPrivateEndpoints'))), array(parameters('accountPrivateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('account_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('account_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('account_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('account_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('account_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + }, + "portalPrivateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the Purview Account Portal." + }, + "copy": { + "count": "[length(if(not(empty(parameters('portalPrivateEndpoints'))), array(parameters('portalPrivateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('portal_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('portal_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('portal_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('portal_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('portal_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + }, + "storageBlobPrivateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the managed storage account blob service." + }, + "copy": { + "count": "[length(if(not(empty(parameters('storageBlobPrivateEndpoints'))), array(parameters('storageBlobPrivateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('blob_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('blob_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('blob_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('blob_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('blob_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + }, + "storageQueuePrivateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the managed storage account queue service." + }, + "copy": { + "count": "[length(if(not(empty(parameters('storageQueuePrivateEndpoints'))), array(parameters('storageQueuePrivateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('queue_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('queue_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('queue_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('queue_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('queue_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } + }, + "eventHubPrivateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the managed Event Hub Namespace." + }, + "copy": { + "count": "[length(if(not(empty(parameters('eventHubPrivateEndpoints'))), array(parameters('eventHubPrivateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('eventHub_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('eventHub_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('eventHub_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('eventHub_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('eventHub_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/purview/account/tests/e2e/max/main.test.bicep b/avm/res/purview/account/tests/e2e/max/main.test.bicep index 0b544313e3..d50eef4117 100644 --- a/avm/res/purview/account/tests/e2e/max/main.test.bicep +++ b/avm/res/purview/account/tests/e2e/max/main.test.bicep @@ -121,9 +121,13 @@ module testDeployment '../../../main.bicep' = [ ] accountPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewAccountPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.purviewAccountPrivateDNSResourceId + } + ] + } service: 'account' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { @@ -135,9 +139,13 @@ module testDeployment '../../../main.bicep' = [ ] portalPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewPortalPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.purviewPortalPrivateDNSResourceId + } + ] + } service: 'portal' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { @@ -147,17 +155,25 @@ module testDeployment '../../../main.bicep' = [ } } { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewPortalPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.purviewPortalPrivateDNSResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] storageBlobPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageBlobPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.storageBlobPrivateDNSResourceId + } + ] + } service: 'blob' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { @@ -169,9 +185,13 @@ module testDeployment '../../../main.bicep' = [ ] storageQueuePrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageQueuePrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.storageQueuePrivateDNSResourceId + } + ] + } service: 'queue' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { @@ -181,17 +201,25 @@ module testDeployment '../../../main.bicep' = [ } } { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageQueuePrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.storageQueuePrivateDNSResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] eventHubPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.eventHubPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.eventHubPrivateDNSResourceId + } + ] + } service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep b/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep index d39ad0c684..dbf48b0d92 100644 --- a/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/purview/account/tests/e2e/waf-aligned/main.test.bicep @@ -87,45 +87,65 @@ module testDeployment '../../../main.bicep' = [ ] accountPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewAccountPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.purviewAccountPrivateDNSResourceId + } + ] + } service: 'account' subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] portalPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.purviewPortalPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.purviewPortalPrivateDNSResourceId + } + ] + } service: 'portal' subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] storageBlobPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageBlobPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.storageBlobPrivateDNSResourceId + } + ] + } service: 'blob' subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] storageQueuePrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.storageQueuePrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.storageQueuePrivateDNSResourceId + } + ] + } service: 'queue' subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] eventHubPrivateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.eventHubPrivateDNSResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.eventHubPrivateDNSResourceId + } + ] + } service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId } diff --git a/avm/res/purview/account/version.json b/avm/res/purview/account/version.json index c177b1bb58..3f863a2bec 100644 --- a/avm/res/purview/account/version.json +++ b/avm/res/purview/account/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/res/recovery-services/vault/README.md b/avm/res/recovery-services/vault/README.md index e91697bcc3..f0756aa9ab 100644 --- a/avm/res/recovery-services/vault/README.md +++ b/avm/res/recovery-services/vault/README.md @@ -626,9 +626,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ] - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -1026,9 +1030,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ], - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "", "tags": { "Environment": "Non-Prod", @@ -1420,9 +1428,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ] - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -1801,9 +1813,13 @@ module vault 'br/public:avm/res/recovery-services/vault:' = { } } ], - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "", "tags": { "Environment": "Non-Prod", @@ -2167,8 +2183,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -2352,19 +2367,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The private DNS zone group to configure for the private endpoint. - Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group config. - Required: No -- Type: array +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` + +The name of the Private DNS Zone Group. + +- Required: No +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -2657,6 +2717,7 @@ Tags of the Recovery Service Vault resource. | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The Name of the recovery services vault. | +| `privateEndpoints` | array | The private endpoints of the recovery services vault. | | `resourceGroupName` | string | The name of the resource group the recovery services vault was created in. | | `resourceId` | string | The resource ID of the recovery services vault. | | `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | @@ -2667,7 +2728,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.6.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/recovery-services/vault/main.bicep b/avm/res/recovery-services/vault/main.bicep index 3814977dbc..5ee99722fa 100644 --- a/avm/res/recovery-services/vault/main.bicep +++ b/avm/res/recovery-services/vault/main.bicep @@ -313,7 +313,7 @@ resource rsv_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-0 } ] -module rsv_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module rsv_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-rsv-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -354,8 +354,7 @@ module rsv_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -397,6 +396,17 @@ output systemAssignedMIPrincipalId string = rsv.?identity.?principalId ?? '' @description('The location the resource was deployed into.') output location string = rsv.location +@description('The private endpoints of the recovery services vault.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: rsv_privateEndpoints[i].outputs.name + resourceId: rsv_privateEndpoints[i].outputs.resourceId + groupId: rsv_privateEndpoints[i].outputs.groupId + customDnsConfig: rsv_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: rsv_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -459,11 +469,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/recovery-services/vault/main.json b/avm/res/recovery-services/vault/main.json index a45d01f251..91ffe8c500 100644 --- a/avm/res/recovery-services/vault/main.json +++ b/avm/res/recovery-services/vault/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "9430653726515425544" + "templateHash": "1317340221517130136" }, "name": "Recovery Services Vaults", "description": "This module deploys a Recovery Services Vault.", @@ -173,21 +173,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -2060,11 +2083,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -2093,13 +2113,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -2351,6 +2392,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -2386,18 +2450,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -2478,7 +2535,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2557,7 +2614,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -2568,28 +2625,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -2597,12 +2678,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -2616,27 +2700,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -2703,6 +2796,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -2753,6 +2853,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('rsv', '2023-01-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the recovery services vault." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('rsv_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('rsv_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('rsv_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('rsv_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('rsv_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep index 13411c7ff9..28e3b85435 100644 --- a/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/max/main.test.bicep @@ -380,9 +380,13 @@ module testDeployment '../../../main.bicep' = [ } } ] - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' diff --git a/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep b/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep index 925915c278..7ad49f1ccb 100644 --- a/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/recovery-services/vault/tests/e2e/waf-aligned/main.test.bicep @@ -380,9 +380,13 @@ module testDeployment '../../../main.bicep' = [ } } ] - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' diff --git a/avm/res/recovery-services/vault/version.json b/avm/res/recovery-services/vault/version.json index c177b1bb58..3f863a2bec 100644 --- a/avm/res/recovery-services/vault/version.json +++ b/avm/res/recovery-services/vault/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/res/relay/namespace/README.md b/avm/res/relay/namespace/README.md index 5ed4c286ac..55d143ec68 100644 --- a/avm/res/relay/namespace/README.md +++ b/avm/res/relay/namespace/README.md @@ -182,9 +182,13 @@ module namespace 'br/public:avm/res/relay/namespace:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'namespace' subnetResourceId: '' tags: { @@ -194,9 +198,13 @@ module namespace 'br/public:avm/res/relay/namespace:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -345,9 +353,13 @@ module namespace 'br/public:avm/res/relay/namespace:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "namespace", "subnetResourceId": "", "tags": { @@ -357,9 +369,13 @@ module namespace 'br/public:avm/res/relay/namespace:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -489,9 +505,13 @@ module namespace 'br/public:avm/res/relay/namespace:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'namespace' subnetResourceId: '' tags: { @@ -600,9 +620,13 @@ module namespace 'br/public:avm/res/relay/namespace:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "namespace", "subnetResourceId": "", "tags": { @@ -929,8 +953,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -1114,19 +1137,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` + +The private DNS zone group to configure for the private endpoint. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The name of the private DNS zone group config. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the Private DNS Zone Group. - Required: No -- Type: array +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -1386,6 +1454,7 @@ The wcf relays to create in the relay namespace. | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the deployed relay namespace. | +| `privateEndpoints` | array | The private endpoints of the relay namespace. | | `resourceGroupName` | string | The resource group of the deployed relay namespace. | | `resourceId` | string | The resource ID of the deployed relay namespace. | @@ -1395,7 +1464,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.6.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/relay/namespace/main.bicep b/avm/res/relay/namespace/main.bicep index a9ec9ccd00..e28a037e51 100644 --- a/avm/res/relay/namespace/main.bicep +++ b/avm/res/relay/namespace/main.bicep @@ -264,7 +264,7 @@ resource namespace_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@202 } ] -module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-namespace-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -305,8 +305,7 @@ module namespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0. 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -345,6 +344,17 @@ output name string = namespace.name @description('The location the resource was deployed into.') output location string = namespace.location +@description('The private endpoints of the relay namespace.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: namespace_privateEndpoints[i].outputs.name + resourceId: namespace_privateEndpoints[i].outputs.resourceId + groupId: namespace_privateEndpoints[i].outputs.groupId + customDnsConfig: namespace_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: namespace_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -399,11 +409,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/relay/namespace/main.json b/avm/res/relay/namespace/main.json index 83e1158785..66c0fbf16e 100644 --- a/avm/res/relay/namespace/main.json +++ b/avm/res/relay/namespace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13811660507923080890" + "templateHash": "10535689791446770792" }, "name": "Relay Namespaces", "description": "This module deploys a Relay Namespace", @@ -150,21 +150,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -1788,11 +1811,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -1821,13 +1841,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -2079,6 +2120,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -2114,18 +2178,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -2206,7 +2263,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -2285,7 +2342,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -2296,28 +2353,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -2325,12 +2406,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -2344,27 +2428,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -2431,6 +2524,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -2474,6 +2574,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('namespace', '2021-11-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the relay namespace." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('namespace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/relay/namespace/tests/e2e/max/main.test.bicep b/avm/res/relay/namespace/tests/e2e/max/main.test.bicep index bcbcb125c7..687c8e3487 100644 --- a/avm/res/relay/namespace/tests/e2e/max/main.test.bicep +++ b/avm/res/relay/namespace/tests/e2e/max/main.test.bicep @@ -182,9 +182,13 @@ module testDeployment '../../../main.bicep' = [ { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' @@ -193,9 +197,13 @@ module testDeployment '../../../main.bicep' = [ } { subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } } ] } diff --git a/avm/res/relay/namespace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/relay/namespace/tests/e2e/waf-aligned/main.test.bicep index 4d8538975c..99ae681c88 100644 --- a/avm/res/relay/namespace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/relay/namespace/tests/e2e/waf-aligned/main.test.bicep @@ -134,9 +134,13 @@ module testDeployment '../../../main.bicep' = [ { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/avm/res/relay/namespace/version.json b/avm/res/relay/namespace/version.json index c177b1bb58..3f863a2bec 100644 --- a/avm/res/relay/namespace/version.json +++ b/avm/res/relay/namespace/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/res/service-bus/namespace/README.md b/avm/res/service-bus/namespace/README.md index 556c0ce46c..91b4f6ae1b 100644 --- a/avm/res/service-bus/namespace/README.md +++ b/avm/res/service-bus/namespace/README.md @@ -295,9 +295,13 @@ module namespace 'br/public:avm/res/service-bus/namespace:' = { } ] name: 'myPrivateEndpoint' - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } privateLinkServiceConnectionName: 'customLinkName' subnetResourceId: '' tags: { @@ -307,9 +311,13 @@ module namespace 'br/public:avm/res/service-bus/namespace:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -561,9 +569,13 @@ module namespace 'br/public:avm/res/service-bus/namespace:' = { } ], "name": "myPrivateEndpoint", - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "privateLinkServiceConnectionName": "customLinkName", "subnetResourceId": "", "tags": { @@ -573,9 +585,13 @@ module namespace 'br/public:avm/res/service-bus/namespace:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -791,9 +807,13 @@ module namespace 'br/public:avm/res/service-bus/namespace:' = { premiumMessagingPartitions: 1 privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'namespace' subnetResourceId: '' tags: { @@ -966,9 +986,13 @@ module namespace 'br/public:avm/res/service-bus/namespace:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "namespace", "subnetResourceId": "", "tags": { @@ -1713,8 +1737,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -1898,19 +1921,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` + +The private DNS zone group to configure for the private endpoint. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The name of the private DNS zone group config. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the Private DNS Zone Group. - Required: No -- Type: array +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -3015,6 +3083,7 @@ Enabling this property creates a Premium Service Bus Namespace in regions suppor | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the deployed service bus namespace. | +| `privateEndpoints` | array | The private endpoints of the service bus namespace. | | `resourceGroupName` | string | The resource group of the deployed service bus namespace. | | `resourceId` | string | The resource ID of the deployed service bus namespace. | | `systemAssignedMIPrincipalId` | string | The principal ID of the system assigned identity. | @@ -3025,7 +3094,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.6.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/service-bus/namespace/main.bicep b/avm/res/service-bus/namespace/main.bicep index 1c26424df2..507297992b 100644 --- a/avm/res/service-bus/namespace/main.bicep +++ b/avm/res/service-bus/namespace/main.bicep @@ -365,7 +365,7 @@ resource serviceBusNamespace_diagnosticSettings 'Microsoft.Insights/diagnosticSe } ] -module serviceBusNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module serviceBusNamespace_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-serviceBusNamespace-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -406,8 +406,7 @@ module serviceBusNamespace_privateEndpoints 'br/public:avm/res/network/private-e 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -453,6 +452,17 @@ output systemAssignedMIPrincipalId string = serviceBusNamespace.?identity.?princ @description('The location the resource was deployed into.') output location string = serviceBusNamespace.location +@description('The private endpoints of the service bus namespace.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: serviceBusNamespace_privateEndpoints[i].outputs.name + resourceId: serviceBusNamespace_privateEndpoints[i].outputs.resourceId + groupId: serviceBusNamespace_privateEndpoints[i].outputs.groupId + customDnsConfig: serviceBusNamespace_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: serviceBusNamespace_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -515,11 +525,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/service-bus/namespace/main.json b/avm/res/service-bus/namespace/main.json index 693c15dc2e..e3bdecdc0f 100644 --- a/avm/res/service-bus/namespace/main.json +++ b/avm/res/service-bus/namespace/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "227465215795701971" + "templateHash": "10964684048264975988" }, "name": "Service Bus Namespaces", "description": "This module deploys a Service Bus Namespace.", @@ -173,21 +173,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -3463,11 +3486,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -3496,13 +3516,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -3754,6 +3795,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -3789,18 +3853,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -3881,7 +3938,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -3960,7 +4017,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -3971,28 +4028,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -4000,12 +4081,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -4019,27 +4103,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -4106,6 +4199,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -4156,6 +4256,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('serviceBusNamespace', '2022-10-01-preview', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the service bus namespace." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('serviceBusNamespace_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep b/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep index 1fc9965264..75f7aac495 100644 --- a/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/max/main.test.bicep @@ -256,9 +256,13 @@ module testDeployment '../../../main.bicep' = [ name: 'myPrivateEndpoint' privateLinkServiceConnectionName: 'customLinkName' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' @@ -285,9 +289,13 @@ module testDeployment '../../../main.bicep' = [ } { subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } } ] managedIdentities: { diff --git a/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep b/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep index cbd896930d..f40c29ea50 100644 --- a/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/service-bus/namespace/tests/e2e/waf-aligned/main.test.bicep @@ -180,9 +180,13 @@ module testDeployment '../../../main.bicep' = [ { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/avm/res/service-bus/namespace/version.json b/avm/res/service-bus/namespace/version.json index 21226dd43f..09c3664cec 100644 --- a/avm/res/service-bus/namespace/version.json +++ b/avm/res/service-bus/namespace/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.6", + "version": "0.7", "pathFilters": [ "./main.json" ] diff --git a/avm/res/signal-r-service/signal-r/README.md b/avm/res/signal-r-service/signal-r/README.md index fc8e01a985..d182a6aca4 100644 --- a/avm/res/signal-r-service/signal-r/README.md +++ b/avm/res/signal-r-service/signal-r/README.md @@ -134,9 +134,13 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -145,9 +149,13 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -249,9 +257,13 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "", "tags": { "Environment": "Non-Prod", @@ -260,9 +272,13 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -354,9 +370,13 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' tags: { Environment: 'Non-Prod' @@ -438,9 +458,13 @@ module signalR 'br/public:avm/res/signal-r-service/signal-r:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "", "tags": { "Environment": "Non-Prod", @@ -697,8 +721,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -882,19 +905,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` + +The private DNS zone group to configure for the private endpoint. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The name of the private DNS zone group config. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the Private DNS Zone Group. - Required: No -- Type: array +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -1210,6 +1278,7 @@ Upstream templates to enable. For more information, see https://learn.microsoft. | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The SignalR name. | +| `privateEndpoints` | array | The private endpoints of the SignalR. | | `resourceGroupName` | string | The SignalR resource group. | | `resourceId` | string | The SignalR resource ID. | @@ -1219,7 +1288,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.6.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/signal-r-service/signal-r/main.bicep b/avm/res/signal-r-service/signal-r/main.bicep index 5e5c88ce39..37b7449350 100644 --- a/avm/res/signal-r-service/signal-r/main.bicep +++ b/avm/res/signal-r-service/signal-r/main.bicep @@ -240,7 +240,7 @@ resource signalR 'Microsoft.SignalRService/signalR@2022-02-01' = { } } -module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-signalR-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -281,8 +281,7 @@ module signalR_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6. 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -332,6 +331,17 @@ output resourceId string = signalR.id @description('The location the resource was deployed into.') output location string = signalR.location +@description('The private endpoints of the SignalR.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: signalR_privateEndpoints[i].outputs.name + resourceId: signalR_privateEndpoints[i].outputs.resourceId + groupId: signalR_privateEndpoints[i].outputs.groupId + customDnsConfig: signalR_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: signalR_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -386,11 +396,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/signal-r-service/signal-r/main.json b/avm/res/signal-r-service/signal-r/main.json index 518c8c4894..6ed88a6fad 100644 --- a/avm/res/signal-r-service/signal-r/main.json +++ b/avm/res/signal-r-service/signal-r/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "9623048216763413627" + "templateHash": "6232258125767604001" }, "name": "SignalR Service SignalR", "description": "This module deploys a SignalR Service SignalR.", @@ -150,21 +150,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -657,11 +680,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -690,13 +710,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -948,6 +989,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -983,18 +1047,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1075,7 +1132,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1154,7 +1211,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1165,28 +1222,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1194,12 +1275,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1213,27 +1297,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -1300,6 +1393,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -1343,6 +1443,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('signalR', '2022-02-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the SignalR." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('signalR_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('signalR_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('signalR_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('signalR_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('signalR_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep index ea1fe1f2b8..8ec75e7dac 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/max/main.test.bicep @@ -84,9 +84,13 @@ module testDeployment '../../../main.bicep' = [ } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' @@ -95,9 +99,13 @@ module testDeployment '../../../main.bicep' = [ } } { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] diff --git a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep index 51ca8dd306..009b496f45 100644 --- a/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/signal-r-service/signal-r/tests/e2e/waf-aligned/main.test.bicep @@ -79,9 +79,13 @@ module testDeployment '../../../main.bicep' = [ } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { 'hidden-title': 'This is visible in the resource name' diff --git a/avm/res/signal-r-service/signal-r/version.json b/avm/res/signal-r-service/signal-r/version.json index c177b1bb58..3f863a2bec 100644 --- a/avm/res/signal-r-service/signal-r/version.json +++ b/avm/res/signal-r-service/signal-r/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ] diff --git a/avm/res/signal-r-service/web-pub-sub/README.md b/avm/res/signal-r-service/web-pub-sub/README.md index 8d9012c74c..224f8310e8 100644 --- a/avm/res/signal-r-service/web-pub-sub/README.md +++ b/avm/res/signal-r-service/web-pub-sub/README.md @@ -136,9 +136,13 @@ module webPubSub 'br/public:avm/res/signal-r-service/web-pub-sub:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'webpubsub' subnetResourceId: '' tags: { @@ -148,9 +152,13 @@ module webPubSub 'br/public:avm/res/signal-r-service/web-pub-sub:' = { } } { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } subnetResourceId: '' } ] @@ -254,9 +262,13 @@ module webPubSub 'br/public:avm/res/signal-r-service/web-pub-sub:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "webpubsub", "subnetResourceId": "", "tags": { @@ -266,9 +278,13 @@ module webPubSub 'br/public:avm/res/signal-r-service/web-pub-sub:' = { } }, { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "subnetResourceId": "" } ] @@ -362,9 +378,13 @@ module webPubSub 'br/public:avm/res/signal-r-service/web-pub-sub:' = { } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - '' - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: '' + } + ] + } service: 'webpubsub' subnetResourceId: '' tags: { @@ -449,9 +469,13 @@ module webPubSub 'br/public:avm/res/signal-r-service/web-pub-sub:' = { "privateEndpoints": { "value": [ { - "privateDnsZoneResourceIds": [ - "" - ], + "privateDnsZoneGroup": { + "privateDnsZoneGroupConfigs": [ + { + "privateDnsZoneResourceId": "" + } + ] + }, "service": "webpubsub", "subnetResourceId": "", "tags": { @@ -666,8 +690,7 @@ Configuration details for private endpoints. For security reasons, it is recomme | [`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. | +| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | | [`privateLinkServiceConnectionName`](#parameter-privateendpointsprivatelinkserviceconnectionname) | string | The name of the private link connection to create. | | [`resourceGroupName`](#parameter-privateendpointsresourcegroupname) | string | Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | @@ -851,19 +874,64 @@ The name of the private endpoint. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneGroupName` +### Parameter: `privateEndpoints.privateDnsZoneGroup` + +The private DNS zone group to configure for the private endpoint. + +- Required: No +- Type: object + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneGroupConfigs`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigs) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupname) | string | The name of the Private DNS Zone Group. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. + +- Required: Yes +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`privateDnsZoneResourceId`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsprivatednszoneresourceid) | string | The resource id of the private DNS zone. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` + +The resource id of the private DNS zone. + +- Required: Yes +- Type: string + +### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. +The name of the private DNS zone group config. - Required: No - Type: string -### Parameter: `privateEndpoints.privateDnsZoneResourceIds` +### Parameter: `privateEndpoints.privateDnsZoneGroup.name` -The private DNS zone groups to associate the private endpoint with. A DNS zone group can support up to 5 DNS zones. +The name of the Private DNS Zone Group. - Required: No -- Type: array +- Type: string ### Parameter: `privateEndpoints.privateLinkServiceConnectionName` @@ -1153,6 +1221,7 @@ Tags of the resource. | `hostName` | string | The Web PubSub hostName. | | `location` | string | The location the resource was deployed into. | | `name` | string | The Web PubSub name. | +| `privateEndpoints` | array | The private endpoints of the Web PubSub. | | `publicPort` | int | The Web PubSub publicPort. | | `resourceGroupName` | string | The Web PubSub resource group. | | `resourceId` | string | The Web PubSub resource ID. | @@ -1165,7 +1234,7 @@ This section gives you an overview of all local-referenced module files (i.e., o | Reference | Type | | :-- | :-- | -| `br/public:avm/res/network/private-endpoint:0.6.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.7.1` | Remote reference | ## Data Collection diff --git a/avm/res/signal-r-service/web-pub-sub/main.bicep b/avm/res/signal-r-service/web-pub-sub/main.bicep index c7cc0e8d77..a3821042f8 100644 --- a/avm/res/signal-r-service/web-pub-sub/main.bicep +++ b/avm/res/signal-r-service/web-pub-sub/main.bicep @@ -189,7 +189,7 @@ resource webPubSub 'Microsoft.SignalRService/webPubSub@2021-10-01' = { } } -module webPubSub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.6.1' = [ +module webPubSub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-webPubSub-PrivateEndpoint-${index}' scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') @@ -230,8 +230,7 @@ module webPubSub_privateEndpoints 'br/public:avm/res/network/private-endpoint:0. 'Full' ).location lock: privateEndpoint.?lock ?? lock - privateDnsZoneGroupName: privateEndpoint.?privateDnsZoneGroupName - privateDnsZoneResourceIds: privateEndpoint.?privateDnsZoneResourceIds + privateDnsZoneGroup: privateEndpoint.?privateDnsZoneGroup roleAssignments: privateEndpoint.?roleAssignments tags: privateEndpoint.?tags ?? tags customDnsConfigs: privateEndpoint.?customDnsConfigs @@ -296,6 +295,17 @@ output systemAssignedMIPrincipalId string = webPubSub.?identity.?principalId ?? @description('The location the resource was deployed into.') output location string = webPubSub.location +@description('The private endpoints of the Web PubSub.') +output privateEndpoints array = [ + for (pe, i) in (!empty(privateEndpoints) ? array(privateEndpoints) : []): { + name: webPubSub_privateEndpoints[i].outputs.name + resourceId: webPubSub_privateEndpoints[i].outputs.resourceId + groupId: webPubSub_privateEndpoints[i].outputs.groupId + customDnsConfig: webPubSub_privateEndpoints[i].outputs.customDnsConfig + networkInterfaceIds: webPubSub_privateEndpoints[i].outputs.networkInterfaceIds + } +] + // =============== // // Definitions // // =============== // @@ -358,11 +368,20 @@ type privateEndpointType = { @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 group to configure for the private endpoint.') + privateDnsZoneGroup: { + @description('Optional. The name of the Private DNS Zone Group.') + name: string? + + @description('Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') + privateDnsZoneGroupConfigs: { + @description('Optional. The name of the private DNS zone group config.') + name: 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('Required. The resource id of the private DNS zone.') + privateDnsZoneResourceId: string + }[] + }? @description('Optional. If Manual Private Link Connection is required.') isManualConnection: bool? diff --git a/avm/res/signal-r-service/web-pub-sub/main.json b/avm/res/signal-r-service/web-pub-sub/main.json index e4bbb1ad2d..5807cd4da1 100644 --- a/avm/res/signal-r-service/web-pub-sub/main.json +++ b/avm/res/signal-r-service/web-pub-sub/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "7275087868796489976" + "templateHash": "3619836062547426326" }, "name": "SignalR Web PubSub Services", "description": "This module deploys a SignalR Web PubSub Service.", @@ -173,21 +173,44 @@ "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" + "privateDnsZoneGroup": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + } + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } }, "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "isManualConnection": { @@ -604,11 +627,8 @@ "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')]" + "privateDnsZoneGroup": { + "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'privateDnsZoneGroup')]" }, "roleAssignments": { "value": "[tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'roleAssignments')]" @@ -637,13 +657,34 @@ "_generator": { "name": "bicep", "version": "0.29.47.4906", - "templateHash": "13720311665093076615" + "templateHash": "1277254088602407590" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, "definitions": { + "privateDnsZoneGroupType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private DNS Zone Group." + } + }, + "privateDnsZoneGroupConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, + "metadata": { + "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + } + } + } + }, "roleAssignmentType": { "type": "array", "items": { @@ -895,6 +936,29 @@ } }, "nullable": true + }, + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" + } + } } }, "parameters": { @@ -930,18 +994,11 @@ "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", + "privateDnsZoneGroup": { + "$ref": "#/definitions/privateDnsZoneGroupType", "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." + "description": "Optional. The private DNS zone group to configure for the private endpoint." } }, "location": { @@ -1022,7 +1079,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.6.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1101,7 +1158,7 @@ ] }, "privateEndpoint_privateDnsZoneGroup": { - "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", + "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", @@ -1112,28 +1169,52 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" - }, - "privateDNSResourceIds": { - "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" + "value": "[tryGet(parameters('privateDnsZoneGroup'), 'name')]" }, "privateEndpointName": { "value": "[parameters('name')]" + }, + "privateDnsZoneConfigs": { + "value": "[parameters('privateDnsZoneGroup').privateDnsZoneGroupConfigs]" } }, "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.29.47.4906", - "templateHash": "15263454436186512874" + "templateHash": "5805178546717255803" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", "owner": "Azure/module-maintainers" }, + "definitions": { + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." + } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." + } + } + }, + "metadata": { + "__bicep_export!": true + } + } + }, "parameters": { "privateEndpointName": { "type": "string", @@ -1141,12 +1222,15 @@ "description": "Conditional. The name of the parent private endpoint. Required if the template is used in a standalone deployment." } }, - "privateDNSResourceIds": { + "privateDnsZoneConfigs": { "type": "array", + "items": { + "$ref": "#/definitions/privateDnsZoneGroupConfigType" + }, "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." + "description": "Required. Array of private DNS zone configurations of the private DNS zone group. A DNS zone group can support up to 5 DNS zones." } }, "name": { @@ -1160,27 +1244,36 @@ "variables": { "copy": [ { - "name": "privateDnsZoneConfigs", - "count": "[length(parameters('privateDNSResourceIds'))]", + "name": "privateDnsZoneConfigsVar", + "count": "[length(parameters('privateDnsZoneConfigs'))]", "input": { - "name": "[last(split(parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')], '/'))]", + "name": "[coalesce(tryGet(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')], 'name'), last(split(parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId, '/')))]", "properties": { - "privateDnsZoneId": "[parameters('privateDNSResourceIds')[copyIndex('privateDnsZoneConfigs')]]" + "privateDnsZoneId": "[parameters('privateDnsZoneConfigs')[copyIndex('privateDnsZoneConfigsVar')].privateDnsZoneResourceId]" } } } ] }, - "resources": [ - { + "resources": { + "privateEndpoint": { + "existing": true, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-11-01", + "name": "[parameters('privateEndpointName')]" + }, + "privateDnsZoneGroup": { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", "apiVersion": "2023-11-01", "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { - "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigs')]" - } + "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" + }, + "dependsOn": [ + "privateEndpoint" + ] } - ], + }, "outputs": { "name": { "type": "string", @@ -1247,6 +1340,13 @@ }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, + "networkInterfaceIds": { + "type": "array", + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." + }, + "value": "[reference('privateEndpoint').networkInterfaces]" + }, "groupId": { "type": "string", "metadata": { @@ -1325,6 +1425,22 @@ "description": "The location the resource was deployed into." }, "value": "[reference('webPubSub', '2021-10-01', 'full').location]" + }, + "privateEndpoints": { + "type": "array", + "metadata": { + "description": "The private endpoints of the Web PubSub." + }, + "copy": { + "count": "[length(if(not(empty(parameters('privateEndpoints'))), array(parameters('privateEndpoints')), createArray()))]", + "input": { + "name": "[reference(format('webPubSub_privateEndpoints[{0}]', copyIndex())).outputs.name.value]", + "resourceId": "[reference(format('webPubSub_privateEndpoints[{0}]', copyIndex())).outputs.resourceId.value]", + "groupId": "[reference(format('webPubSub_privateEndpoints[{0}]', copyIndex())).outputs.groupId.value]", + "customDnsConfig": "[reference(format('webPubSub_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfig.value]", + "networkInterfaceIds": "[reference(format('webPubSub_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceIds.value]" + } + } } } } \ No newline at end of file diff --git a/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep b/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep index dfbb4884b2..61f7b3dc9d 100644 --- a/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep +++ b/avm/res/signal-r-service/web-pub-sub/tests/e2e/max/main.test.bicep @@ -83,9 +83,13 @@ module testDeployment '../../../main.bicep' = [ } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } service: 'webpubsub' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { @@ -95,9 +99,13 @@ module testDeployment '../../../main.bicep' = [ } } { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } subnetResourceId: nestedDependencies.outputs.subnetResourceId } ] diff --git a/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep b/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep index a1ba316a76..34172c1749 100644 --- a/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep +++ b/avm/res/signal-r-service/web-pub-sub/tests/e2e/waf-aligned/main.test.bicep @@ -78,9 +78,13 @@ module testDeployment '../../../main.bicep' = [ } privateEndpoints: [ { - privateDnsZoneResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + privateDnsZoneGroup: { + privateDnsZoneGroupConfigs: [ + { + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId + } + ] + } service: 'webpubsub' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/avm/res/signal-r-service/web-pub-sub/version.json b/avm/res/signal-r-service/web-pub-sub/version.json index c177b1bb58..3f863a2bec 100644 --- a/avm/res/signal-r-service/web-pub-sub/version.json +++ b/avm/res/signal-r-service/web-pub-sub/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.3", + "version": "0.4", "pathFilters": [ "./main.json" ]