From 098687e4f1e0911852ebf257304b6655d594a020 Mon Sep 17 00:00:00 2001 From: Kris Baranek <20225789+krbar@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:07:18 +0200 Subject: [PATCH] PE Update kusto cluster, appgw, purview --- avm/res/kusto/cluster/main.bicep | 62 +++++++--- .../cluster/tests/e2e/pe/dependencies.bicep | 68 +++++++++++ .../cluster/tests/e2e/pe/main.test.bicep | 90 +++++++++++++++ avm/res/kusto/cluster/version.json | 2 +- .../network/application-gateway/main.bicep | 33 ++++-- .../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/main.bicep | 108 ++++++++++++++---- .../account/tests/e2e/max/main.test.bicep | 70 ++++++++---- .../tests/e2e/waf-aligned/main.test.bicep | 50 +++++--- avm/res/purview/account/version.json | 2 +- 13 files changed, 412 insertions(+), 96 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/kusto/cluster/main.bicep b/avm/res/kusto/cluster/main.bicep index 345e2b7317..2805fdc6e1 100644 --- a/avm/res/kusto/cluster/main.bicep +++ b/avm/res/kusto/cluster/main.bicep @@ -301,12 +301,13 @@ module kustoCluster_principalAssignments 'principal-assignment/main.bicep' = [ } ] -module kustoCluster_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.4.0' = [ +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 +320,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 +342,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 +357,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 +489,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 +522,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 +542,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 +564,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/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..9e1c347860 --- /dev/null +++ b/avm/res/kusto/cluster/tests/e2e/pe/main.test.bicep @@ -0,0 +1,90 @@ +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}-search.searchservices-${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' + 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/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/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/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/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" ]