diff --git a/avm/res/insights/private-link-scope/README.md b/avm/res/insights/private-link-scope/README.md index 4f0d01138d..f6fc9d3f49 100644 --- a/avm/res/insights/private-link-scope/README.md +++ b/avm/res/insights/private-link-scope/README.md @@ -1122,32 +1122,22 @@ Specifies the access mode of ingestion or queries through associated private end - Required: No - Type: object -**Optional parameters** +**Required parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`exclusions`](#parameter-accessmodesettingsexclusions) | array | List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning. | | [`ingestionAccessMode`](#parameter-accessmodesettingsingestionaccessmode) | string | Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. | | [`queryAccessMode`](#parameter-accessmodesettingsqueryaccessmode) | string | Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. | -### Parameter: `accessModeSettings.exclusions` - -List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning. - -- Required: No -- Type: array - -**Required parameters** +**Optional parameters** | Parameter | Type | Description | | :-- | :-- | :-- | -| [`ingestionAccessMode`](#parameter-accessmodesettingsexclusionsingestionaccessmode) | string | Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion. | -| [`privateEndpointConnectionName`](#parameter-accessmodesettingsexclusionsprivateendpointconnectionname) | string | The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings. | -| [`queryAccessMode`](#parameter-accessmodesettingsexclusionsqueryaccessmode) | string | Specifies the access mode of queries through the specified private endpoint connection in the exclusion. | +| [`exclusions`](#parameter-accessmodesettingsexclusions) | array | List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning. | -### Parameter: `accessModeSettings.exclusions.ingestionAccessMode` +### Parameter: `accessModeSettings.ingestionAccessMode` -Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion. +Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. - Required: Yes - Type: string @@ -1159,16 +1149,9 @@ Specifies the access mode of ingestion through the specified private endpoint co ] ``` -### Parameter: `accessModeSettings.exclusions.privateEndpointConnectionName` - -The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings. - -- Required: Yes -- Type: string - -### Parameter: `accessModeSettings.exclusions.queryAccessMode` +### Parameter: `accessModeSettings.queryAccessMode` -Specifies the access mode of queries through the specified private endpoint connection in the exclusion. +Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. - Required: Yes - Type: string @@ -1180,11 +1163,26 @@ Specifies the access mode of queries through the specified private endpoint conn ] ``` -### Parameter: `accessModeSettings.ingestionAccessMode` +### Parameter: `accessModeSettings.exclusions` -Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. +List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning. - Required: No +- Type: array + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`ingestionAccessMode`](#parameter-accessmodesettingsexclusionsingestionaccessmode) | string | Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion. | +| [`privateEndpointConnectionName`](#parameter-accessmodesettingsexclusionsprivateendpointconnectionname) | string | The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings. | +| [`queryAccessMode`](#parameter-accessmodesettingsexclusionsqueryaccessmode) | string | Specifies the access mode of queries through the specified private endpoint connection in the exclusion. | + +### Parameter: `accessModeSettings.exclusions.ingestionAccessMode` + +Specifies the access mode of ingestion through the specified private endpoint connection in the exclusion. + +- Required: Yes - Type: string - Allowed: ```Bicep @@ -1194,11 +1192,18 @@ Specifies the default access mode of ingestion through associated private endpoi ] ``` -### Parameter: `accessModeSettings.queryAccessMode` +### Parameter: `accessModeSettings.exclusions.privateEndpointConnectionName` -Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value. +The private endpoint connection name associated to the private endpoint on which we want to apply the specific access mode settings. -- Required: No +- Required: Yes +- Type: string + +### Parameter: `accessModeSettings.exclusions.queryAccessMode` + +Specifies the access mode of queries through the specified private endpoint connection in the exclusion. + +- Required: Yes - Type: string - Allowed: ```Bicep @@ -1277,22 +1282,22 @@ Configuration details for private endpoints. For security reasons, it is recomme | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-privateendpointsapplicationsecuritygroupresourceids) | array | Application security groups in which the Private Endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-privateendpointscustomdnsconfigs) | array | Custom DNS configurations. | -| [`customNetworkInterfaceName`](#parameter-privateendpointscustomnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | +| [`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. | +| [`ipConfigurations`](#parameter-privateendpointsipconfigurations) | array | A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. | | [`isManualConnection`](#parameter-privateendpointsismanualconnection) | bool | If Manual Private Link Connection is required. | -| [`location`](#parameter-privateendpointslocation) | string | The location to deploy the private endpoint to. | +| [`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. | -| [`privateDnsZoneGroup`](#parameter-privateendpointsprivatednszonegroup) | object | The private DNS zone group to configure for the private endpoint. | +| [`name`](#parameter-privateendpointsname) | string | The name of the Private Endpoint. | +| [`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. | +| [`resourceGroupResourceId`](#parameter-privateendpointsresourcegroupresourceid) | string | The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. | | [`roleAssignments`](#parameter-privateendpointsroleassignments) | array | Array of role assignments to create. | -| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". | -| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/resource groups in this deployment. | +| [`service`](#parameter-privateendpointsservice) | string | The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. | +| [`tags`](#parameter-privateendpointstags) | object | Tags to be applied on all resources/Resource Groups in this deployment. | ### Parameter: `privateEndpoints.subnetResourceId` @@ -1303,7 +1308,7 @@ Resource ID of the subnet where the endpoint needs to be created. ### Parameter: `privateEndpoints.applicationSecurityGroupResourceIds` -Application security groups in which the private endpoint IP configuration is included. +Application security groups in which the Private Endpoint IP configuration is included. - Required: No - Type: array @@ -1343,7 +1348,7 @@ FQDN that resolves to private endpoint IP address. ### Parameter: `privateEndpoints.customNetworkInterfaceName` -The custom name of the network interface attached to the private endpoint. +The custom name of the network interface attached to the Private Endpoint. - Required: No - Type: string @@ -1357,7 +1362,7 @@ Enable/Disable usage telemetry for module. ### Parameter: `privateEndpoints.ipConfigurations` -A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. +A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints. - Required: No - Type: array @@ -1421,7 +1426,7 @@ If Manual Private Link Connection is required. ### Parameter: `privateEndpoints.location` -The location to deploy the private endpoint to. +The location to deploy the Private Endpoint to. - Required: No - Type: string @@ -1471,14 +1476,14 @@ A message passed to the owner of the remote resource with the manual connection ### Parameter: `privateEndpoints.name` -The name of the private endpoint. +The name of the Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.privateDnsZoneGroup` -The private DNS zone group to configure for the private endpoint. +The private DNS Zone Group to configure for the Private Endpoint. - Required: No - Type: object @@ -1487,7 +1492,7 @@ The private DNS zone group to configure for the private endpoint. | 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. | +| [`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** @@ -1497,7 +1502,7 @@ The private DNS zone group to configure for the private endpoint. ### 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. +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 @@ -1512,7 +1517,7 @@ The private DNS zone groups to associate the private endpoint. A DNS zone group | Parameter | Type | Description | | :-- | :-- | :-- | -| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS zone group config. | +| [`name`](#parameter-privateendpointsprivatednszonegroupprivatednszonegroupconfigsname) | string | The name of the private DNS Zone Group config. | ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.privateDnsZoneResourceId` @@ -1523,7 +1528,7 @@ The resource id of the private DNS zone. ### Parameter: `privateEndpoints.privateDnsZoneGroup.privateDnsZoneGroupConfigs.name` -The name of the private DNS zone group config. +The name of the private DNS Zone Group config. - Required: No - Type: string @@ -1542,9 +1547,9 @@ The name of the private link connection to create. - Required: No - Type: string -### Parameter: `privateEndpoints.resourceGroupName` +### Parameter: `privateEndpoints.resourceGroupResourceId` -Specify if you want to deploy the Private Endpoint into a different resource group than the main resource. +The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used. - Required: No - Type: string @@ -1565,7 +1570,7 @@ Array of role assignments to create. - `'Owner'` - `'Private DNS Zone Contributor'` - `'Reader'` - - `'Role Based Access Control Administrator (Preview)'` + - `'Role Based Access Control Administrator'` **Required parameters** @@ -1659,14 +1664,14 @@ The principal type of the assigned principal ID. ### Parameter: `privateEndpoints.service` -The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory". +The subresource to deploy the Private Endpoint for. For example "vault" for a Key Vault Private Endpoint. - Required: No - Type: string ### Parameter: `privateEndpoints.tags` -Tags to be applied on all resources/resource groups in this deployment. +Tags to be applied on all resources/Resource Groups in this deployment. - Required: No - Type: object @@ -1834,7 +1839,8 @@ 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.7.1` | Remote reference | +| `br/public:avm/res/network/private-endpoint:0.10.1` | Remote reference | +| `br/public:avm/utl/types/avm-common-types:0.5.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 f0d1c0601a..7b8f8cc657 100644 --- a/avm/res/insights/private-link-scope/main.bicep +++ b/avm/res/insights/private-link-scope/main.bicep @@ -9,22 +9,25 @@ param name string * Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured. * Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode.''') -param accessModeSettings accessModeType +param accessModeSettings accessModeType? @description('Optional. The location of the private link scope. Should be global.') param location string = 'global' +import { lockType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. The lock settings of the service.') -param lock lockType +param lock lockType? +import { roleAssignmentType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Array of role assignments to create.') -param roleAssignments roleAssignmentType +param roleAssignments roleAssignmentType[]? @description('Optional. Configuration details for Azure Monitor Resources.') -param scopedResources scopedResourceType +param scopedResources scopedResourceType[]? +import { privateEndpointSingleServiceType } from 'br/public:avm/utl/types/avm-common-types:0.5.1' @description('Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible.') -param privateEndpoints privateEndpointType +param privateEndpoints privateEndpointSingleServiceType[]? @description('Optional. Resource tags.') param tags object? @@ -117,17 +120,15 @@ resource privateLinkScope 'microsoft.insights/privateLinkScopes@2021-07-01-previ location: location tags: tags properties: { - accessModeSettings: !empty(privateEndpoints) + accessModeSettings: accessModeSettings ?? (!empty(privateEndpoints) ? { - ingestionAccessMode: accessModeSettings.?ingestionAccessMode ?? 'PrivateOnly' - queryAccessMode: accessModeSettings.?queryAccessMode ?? 'PrivateOnly' - exclusions: accessModeSettings.?exclusions ?? [] - } - : accessModeSettings ?? { - ingestionAccessMode: accessModeSettings.?ingestionAccessMode ?? 'Open' - queryAccessMode: accessModeSettings.?queryAccessMode ?? 'Open' - exclusions: accessModeSettings.?exclusions ?? [] + ingestionAccessMode: 'PrivateOnly' + queryAccessMode: 'PrivateOnly' } + : { + ingestionAccessMode: 'Open' + queryAccessMode: 'Open' + }) } } @@ -153,10 +154,18 @@ resource privateLinkScope_lock 'Microsoft.Authorization/locks@2020-05-01' = if ( scope: privateLinkScope } -module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.7.1' = [ +module privateLinkScope_privateEndpoints 'br/public:avm/res/network/private-endpoint:0.10.1' = [ for (privateEndpoint, index) in (privateEndpoints ?? []): { name: '${uniqueString(deployment().name, location)}-privateLinkScope-PrivateEndpoint-${index}' - scope: resourceGroup(privateEndpoint.?resourceGroupName ?? '') + scope: !empty(privateEndpoint.?resourceGroupResourceId) + ? resourceGroup( + split((privateEndpoint.?resourceGroupResourceId ?? '//'), '/')[2], + split((privateEndpoint.?resourceGroupResourceId ?? '////'), '/')[4] + ) + : resourceGroup( + split((privateEndpoint.?subnetResourceId ?? '//'), '/')[2], + split((privateEndpoint.?subnetResourceId ?? '////'), '/')[4] + ) params: { name: privateEndpoint.?name ?? 'pep-${last(split(privateLinkScope.id, '/'))}-${privateEndpoint.?service ?? 'azuremonitor'}-${index}' privateLinkServiceConnections: privateEndpoint.?isManualConnection != true @@ -237,13 +246,13 @@ output resourceGroupName string = resourceGroup().name output location string = privateLinkScope.location @description('The private endpoints of the private link scope.') -output privateEndpoints array = [ +output privateEndpoints privateEndpointOutputType[] = [ 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 + groupId: privateLinkScope_privateEndpoints[i].outputs.?groupId! + customDnsConfigs: privateLinkScope_privateEndpoints[i].outputs.customDnsConfigs + networkInterfaceResourceIds: privateLinkScope_privateEndpoints[i].outputs.networkInterfaceResourceIds } ] @@ -251,135 +260,41 @@ output privateEndpoints array = [ // Definitions // // =============== // -type lockType = { - @description('Optional. Specify the name of lock.') - name: string? - - @description('Optional. Specify the type of lock.') - kind: ('CanNotDelete' | 'ReadOnly' | 'None')? -}? - -type roleAssignmentType = { - @description('Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated.') - name: string? - - @description('Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') - roleDefinitionIdOrName: string - - @description('Required. The principal ID of the principal (user/group/identity) to assign the role to.') - principalId: string - - @description('Optional. The principal type of the assigned principal ID.') - principalType: ('ServicePrincipal' | 'Group' | 'User' | 'ForeignGroup' | 'Device')? - - @description('Optional. The description of the role assignment.') - description: string? - - @description('Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase "foo_storage_container".') - condition: string? - - @description('Optional. Version of the condition.') - conditionVersion: '2.0'? - - @description('Optional. The Resource Id of the delegated managed identity resource.') - delegatedManagedIdentityResourceId: string? -}[]? - -type privateEndpointType = { - @description('Optional. The name of the private endpoint.') - name: string? - - @description('Optional. The location to deploy the private endpoint to.') - location: string? - - @description('Optional. The name of the private link connection to create.') - privateLinkServiceConnectionName: string? - - @description('Optional. The subresource to deploy the private endpoint for. For example "vault", "mysqlServer" or "dataFactory".') - service: string? - - @description('Required. Resource ID of the subnet where the endpoint needs to be created.') - subnetResourceId: string - - @description('Optional. The 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('Required. The resource id of the private DNS zone.') - privateDnsZoneResourceId: string - }[] - }? +@export() +@description('The type for a private endpoint output.') +type privateEndpointOutputType = { + @description('The name of the private endpoint.') + name: string - @description('Optional. If Manual Private Link Connection is required.') - isManualConnection: bool? + @description('The resource ID of the private endpoint.') + resourceId: string - @description('Optional. A message passed to the owner of the remote resource with the manual connection request.') - @maxLength(140) - manualConnectionRequestMessage: string? + @description('The group Id for the private endpoint Group.') + groupId: string? - @description('Optional. Custom DNS configurations.') + @description('The custom DNS configurations of the private endpoint.') customDnsConfigs: { - @description('Optional. FQDN that resolves to private endpoint IP address.') + @description('FQDN that resolves to private endpoint IP address.') fqdn: string? - @description('Required. A list of private IP addresses of the private endpoint.') + @description('A list of private IP addresses of the private endpoint.') ipAddresses: string[] - }[]? - - @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') - ipConfigurations: { - @description('Required. The name of the resource that is unique within a resource group.') - name: string - - @description('Required. Properties of private endpoint IP configurations.') - properties: { - @description('Required. The ID of a group obtained from the remote resource that this private endpoint should connect to.') - groupId: string - - @description('Required. The member name of a group obtained from the remote resource that this private endpoint should connect to.') - memberName: string - - @description('Required. A private IP address obtained from the private endpoint\'s subnet.') - privateIPAddress: string - } - }[]? + }[] - @description('Optional. Application security groups in which the private endpoint IP configuration is included.') - applicationSecurityGroupResourceIds: string[]? - - @description('Optional. The custom name of the network interface attached to the private endpoint.') - customNetworkInterfaceName: string? - - @description('Optional. Specify the type of lock.') - lock: lockType - - @description('Optional. Array of role assignments to create.') - roleAssignments: roleAssignmentType - - @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') - tags: object? - - @description('Optional. Enable/Disable usage telemetry for module.') - enableTelemetry: bool? - - @description('Optional. Specify if you want to deploy the Private Endpoint into a different resource group than the main resource.') - resourceGroupName: string? -}[]? + @description('The IDs of the network interfaces associated with the private endpoint.') + networkInterfaceResourceIds: string[] +} +@export() type scopedResourceType = { @description('Required. Name of the private link scoped resource.') name: string @description('Required. The resource ID of the scoped Azure monitor resource.') linkedResourceId: string -}[]? +} +@export() type accessModeType = { @description('Optional. List of exclusions that override the default access mode settings for specific private endpoint connections. Exclusions for the current created Private endpoints can only be applied post initial provisioning.') exclusions: { @@ -393,9 +308,9 @@ type accessModeType = { queryAccessMode: 'Open' | 'PrivateOnly' }[]? - @description('Optional. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value.') - ingestionAccessMode: 'Open' | 'PrivateOnly'? + @description('Required. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value.') + ingestionAccessMode: 'Open' | 'PrivateOnly' - @description('Optional. Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value.') - queryAccessMode: 'Open' | 'PrivateOnly'? -}? + @description('Required. Specifies the default access mode of queries through associated private endpoints in scope. Default is "Open" if no private endpoints are configured and will be set to "PrivateOnly" if private endpoints are configured. Override default behaviour by explicitly providing a value.') + queryAccessMode: 'Open' | 'PrivateOnly' +} diff --git a/avm/res/insights/private-link-scope/main.json b/avm/res/insights/private-link-scope/main.json index 7717146bfa..36bf35fb5e 100644 --- a/avm/res/insights/private-link-scope/main.json +++ b/avm/res/insights/private-link-scope/main.json @@ -5,351 +5,96 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "8291521551754556445" + "version": "0.33.93.31351", + "templateHash": "14398588841624417655" }, "name": "Azure Monitor Private Link Scopes", "description": "This module deploys an Azure Monitor Private Link Scope." }, "definitions": { - "lockType": { + "privateEndpointOutputType": { "type": "object", "properties": { "name": { "type": "string", - "nullable": true, "metadata": { - "description": "Optional. Specify the name of lock." + "description": "The name of the private endpoint." } }, - "kind": { + "resourceId": { "type": "string", - "allowedValues": [ - "CanNotDelete", - "None", - "ReadOnly" - ], - "nullable": true, "metadata": { - "description": "Optional. Specify the type of lock." + "description": "The resource ID of the private endpoint." } - } - }, - "nullable": true - }, - "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": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." - } - }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + }, + "groupId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "The group Id for the private endpoint Group." } - } - }, - "nullable": true - }, - "privateEndpointType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private endpoint." - } - }, - "location": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The location to deploy the private endpoint to." - } - }, - "privateLinkServiceConnectionName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The name of the private link connection to create." - } - }, - "service": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The subresource to deploy the private endpoint for. For example \"vault\", \"mysqlServer\" or \"dataFactory\"." - } - }, - "subnetResourceId": { - "type": "string", - "metadata": { - "description": "Required. Resource ID of the subnet where the endpoint needs to be created." - } - }, - "privateDnsZoneGroup": { + }, + "customDnsConfigs": { + "type": "array", + "items": { "type": "object", "properties": { - "name": { + "fqdn": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the Private DNS Zone Group." + "description": "FQDN that resolves to private endpoint IP address." } }, - "privateDnsZoneGroupConfigs": { + "ipAddresses": { "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." - } - } - } + "type": "string" }, "metadata": { - "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." + "description": "A list of private IP addresses of the private endpoint." } } - }, - "nullable": true, - "metadata": { - "description": "Optional. The private DNS zone group to configure for the private endpoint." - } - }, - "isManualConnection": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. If Manual Private Link Connection is required." } }, - "manualConnectionRequestMessage": { - "type": "string", - "nullable": true, - "maxLength": 140, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." - } - }, - "customDnsConfigs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. FQDN that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. Custom DNS configurations." - } - }, - "ipConfigurations": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "memberName": { - "type": "string", - "metadata": { - "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } - } - }, - "nullable": true, - "metadata": { - "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." - } - }, - "applicationSecurityGroupResourceIds": { - "type": "array", - "items": { - "type": "string" - }, - "nullable": true, - "metadata": { - "description": "Optional. Application security groups in which the private endpoint IP configuration is included." - } - }, - "customNetworkInterfaceName": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The custom name of the network interface attached to the private endpoint." - } - }, - "lock": { - "$ref": "#/definitions/lockType", - "metadata": { - "description": "Optional. Specify the type of lock." - } - }, - "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", - "metadata": { - "description": "Optional. Array of role assignments to create." - } - }, - "tags": { - "type": "object", - "nullable": true, - "metadata": { - "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." - } - }, - "enableTelemetry": { - "type": "bool", - "nullable": true, - "metadata": { - "description": "Optional. Enable/Disable usage telemetry for module." - } + "metadata": { + "description": "The custom DNS configurations of the private endpoint." + } + }, + "networkInterfaceResourceIds": { + "type": "array", + "items": { + "type": "string" }, - "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." - } + "metadata": { + "description": "The IDs of the network interfaces associated with the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true, + "description": "The type for a private endpoint output." + } }, "scopedResourceType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. Name of the private link scoped resource." - } - }, - "linkedResourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the scoped Azure monitor resource." - } + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the private link scoped resource." + } + }, + "linkedResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of the scoped Azure monitor resource." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "accessModeType": { "type": "object", @@ -398,9 +143,8 @@ "Open", "PrivateOnly" ], - "nullable": true, "metadata": { - "description": "Optional. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value." + "description": "Required. Specifies the default access mode of ingestion through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value." } }, "queryAccessMode": { @@ -409,13 +153,370 @@ "Open", "PrivateOnly" ], + "metadata": { + "description": "Required. Specifies the default access mode of queries through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "_1.privateEndpointCustomDnsConfigType": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" + }, + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } + }, + "_1.privateEndpointIpConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, + "properties": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "memberName": { + "type": "string", + "metadata": { + "description": "Required. The member name of a group obtained from the remote resource that this private endpoint should connect to." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } + } + }, + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } + }, + "_1.privateEndpointPrivateDnsZoneGroupType": { + "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." + } + } + }, + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], "nullable": true, "metadata": { - "description": "Optional. Specifies the default access mode of queries through associated private endpoints in scope. Default is \"Open\" if no private endpoints are configured and will be set to \"PrivateOnly\" if private endpoints are configured. Override default behaviour by explicitly providing a value." + "description": "Optional. Specify the type of lock." } } }, - "nullable": true + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } + }, + "privateEndpointSingleServiceType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Private Endpoint." + } + }, + "location": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The location to deploy the Private Endpoint to." + } + }, + "privateLinkServiceConnectionName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private link connection to create." + } + }, + "service": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The subresource to deploy the Private Endpoint for. For example \"vault\" for a Key Vault Private Endpoint." + } + }, + "subnetResourceId": { + "type": "string", + "metadata": { + "description": "Required. Resource ID of the subnet where the endpoint needs to be created." + } + }, + "resourceGroupResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The resource ID of the Resource Group the Private Endpoint will be created in. If not specified, the Resource Group of the provided Virtual Network Subnet is used." + } + }, + "privateDnsZoneGroup": { + "$ref": "#/definitions/_1.privateEndpointPrivateDnsZoneGroupType", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS Zone Group to configure for the Private Endpoint." + } + }, + "isManualConnection": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. If Manual Private Link Connection is required." + } + }, + "manualConnectionRequestMessage": { + "type": "string", + "nullable": true, + "maxLength": 140, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with the manual connection request." + } + }, + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointCustomDnsConfigType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Custom DNS configurations." + } + }, + "ipConfigurations": { + "type": "array", + "items": { + "$ref": "#/definitions/_1.privateEndpointIpConfigurationType" + }, + "nullable": true, + "metadata": { + "description": "Optional. A list of IP configurations of the Private Endpoint. This will be used to map to the first-party Service endpoints." + } + }, + "applicationSecurityGroupResourceIds": { + "type": "array", + "items": { + "type": "string" + }, + "nullable": true, + "metadata": { + "description": "Optional. Application security groups in which the Private Endpoint IP configuration is included." + } + }, + "customNetworkInterfaceName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The custom name of the network interface attached to the Private Endpoint." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + }, + "roleAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, + "metadata": { + "description": "Optional. Array of role assignments to create." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags to be applied on all resources/Resource Groups in this deployment." + } + }, + "enableTelemetry": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable usage telemetry for module." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a private endpoint. To be used if the private endpoint's default service / groupId can be assumed (i.e., for services that only have one Private Endpoint type like 'vault' for key vault).", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } + }, + "roleAssignmentType": { + "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": { + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + }, + "metadata": { + "description": "An AVM-aligned type for a role assignment.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" + } + } } }, "parameters": { @@ -428,6 +529,7 @@ }, "accessModeSettings": { "$ref": "#/definitions/accessModeType", + "nullable": true, "metadata": { "description": "Optional. Specifies the access mode of ingestion or queries through associated private endpoints in scope. For security reasons, it is recommended to use PrivateOnly whenever possible to avoid data exfiltration.\n\n* Private Only - This mode allows the connected virtual network to reach only Private Link resources. It is the most secure mode and is set as the default when the `privateEndpoints` parameter is configured.\n* Open - Allows the connected virtual network to reach both Private Link resources and the resources not in the AMPLS resource. Data exfiltration cannot be prevented in this mode." } @@ -441,24 +543,37 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } }, "scopedResources": { - "$ref": "#/definitions/scopedResourceType", + "type": "array", + "items": { + "$ref": "#/definitions/scopedResourceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for Azure Monitor Resources." } }, "privateEndpoints": { - "$ref": "#/definitions/privateEndpointType", + "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointSingleServiceType" + }, + "nullable": true, "metadata": { "description": "Optional. Configuration details for private endpoints. For security reasons, it is recommended to use private endpoints whenever possible." } @@ -531,7 +646,7 @@ "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "accessModeSettings": "[if(not(empty(parameters('privateEndpoints'))), createObject('ingestionAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'ingestionAccessMode'), 'PrivateOnly'), 'queryAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'queryAccessMode'), 'PrivateOnly'), 'exclusions', coalesce(tryGet(parameters('accessModeSettings'), 'exclusions'), createArray())), coalesce(parameters('accessModeSettings'), createObject('ingestionAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'ingestionAccessMode'), 'Open'), 'queryAccessMode', coalesce(tryGet(parameters('accessModeSettings'), 'queryAccessMode'), 'Open'), 'exclusions', coalesce(tryGet(parameters('accessModeSettings'), 'exclusions'), createArray()))))]" + "accessModeSettings": "[coalesce(parameters('accessModeSettings'), if(not(empty(parameters('privateEndpoints'))), createObject('ingestionAccessMode', 'PrivateOnly', 'queryAccessMode', 'PrivateOnly'), createObject('ingestionAccessMode', 'Open', 'queryAccessMode', 'Open')))]" } }, "privateLinkScope_lock": { @@ -600,8 +715,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15902182804479467110" + "version": "0.33.93.31351", + "templateHash": "18319290317274254807" }, "name": "Private Link Scope Scoped Resources", "description": "This module deploys a Private Link Scope Scoped Resource." @@ -675,7 +790,6 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('{0}-privateLinkScope-PrivateEndpoint-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "resourceGroup": "[coalesce(tryGet(coalesce(parameters('privateEndpoints'), createArray())[copyIndex()], 'resourceGroupName'), '')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -728,12 +842,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "1277254088602407590" + "version": "0.33.13.18514", + "templateHash": "15954548978129725136" }, "name": "Private Endpoints", - "description": "This module deploys a Private Endpoint.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint." }, "definitions": { "privateDnsZoneGroupType": { @@ -755,80 +868,118 @@ "description": "Required. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } } + }, + "metadata": { + "__bicep_export!": true } }, - "roleAssignmentType": { - "type": "array", - "items": { - "type": "object", + "ipConfigurationType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the resource that is unique within a resource group." + } + }, "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": { - "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." - } - }, - "principalId": { - "type": "string", - "metadata": { - "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." - } - }, - "principalType": { - "type": "string", - "allowedValues": [ - "Device", - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ], - "nullable": true, - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The description of the role assignment." + "type": "object", + "properties": { + "groupId": { + "type": "string", + "metadata": { + "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. 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. If used with private link service connection, this property must be defined as empty string." + } + }, + "privateIPAddress": { + "type": "string", + "metadata": { + "description": "Required. A private IP address obtained from the private endpoint's subnet." + } } }, - "condition": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + "metadata": { + "description": "Required. Properties of private endpoint IP configurations." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "privateLinkServiceConnectionType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the private link service connection." + } + }, + "properties": { + "type": "object", + "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. If used with private link service connection, this property must be defined as empty string array `[]`." + } + }, + "privateLinkServiceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of private link service." + } + }, + "requestMessage": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." + } } }, - "conditionVersion": { - "type": "string", - "allowedValues": [ - "2.0" - ], - "nullable": true, - "metadata": { - "description": "Optional. Version of the condition." - } + "metadata": { + "description": "Required. Properties of private link service connection." + } + } + }, + "metadata": { + "__bicep_export!": true + } + }, + "customDnsConfigType": { + "type": "object", + "properties": { + "fqdn": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. FQDN that resolves to private endpoint IP address." + } + }, + "ipAddresses": { + "type": "array", + "items": { + "type": "string" }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. The Resource Id of the delegated managed identity resource." - } + "metadata": { + "description": "Required. A list of private IP addresses of the private endpoint." } } }, - "nullable": true + "metadata": { + "__bicep_export!": true + } }, "lockType": { "type": "object", @@ -853,182 +1004,108 @@ } } }, - "nullable": true - }, - "ipConfigurationsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the resource that is unique within a resource group." - } - }, - "properties": { - "type": "object", - "properties": { - "groupId": { - "type": "string", - "metadata": { - "description": "Required. The ID of a group obtained from the remote resource that this private endpoint should connect to. 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. If used with private link service connection, this property must be defined as empty string." - } - }, - "privateIPAddress": { - "type": "string", - "metadata": { - "description": "Required. A private IP address obtained from the private endpoint's subnet." - } - } - }, - "metadata": { - "description": "Required. Properties of private endpoint IP configurations." - } - } + "metadata": { + "description": "An AVM-aligned type for a lock.", + "__bicep_imported_from!": { + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } - }, - "nullable": true + } }, - "manualPrivateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "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": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + "privateDnsZoneGroupConfigType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group config." } - } - }, - "nullable": true - }, - "privateLinkServiceConnectionsType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "metadata": { - "description": "Required. The name of the private link service connection." - } - }, - "properties": { - "type": "object", - "properties": { - "groupIds": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "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": { - "type": "string", - "metadata": { - "description": "Required. The resource id of private link service." - } - }, - "requestMessage": { - "type": "string", - "nullable": true, - "metadata": { - "description": "Optional. A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars." - } - } - }, - "metadata": { - "description": "Required. Properties of private link service connection." - } + }, + "privateDnsZoneResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource id of the private DNS zone." } } }, - "nullable": true - }, - "customDnsConfigType": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fqdn": { - "type": "string", - "metadata": { - "description": "Required. Fqdn that resolves to private endpoint IP address." - } - }, - "ipAddresses": { - "type": "array", - "items": { - "type": "string" - }, - "metadata": { - "description": "Required. A list of private IP addresses of the private endpoint." - } - } + "metadata": { + "__bicep_imported_from!": { + "sourceTemplate": "private-dns-zone-group/main.bicep" } - }, - "nullable": true + } }, - "privateDnsZoneGroupConfigType": { + "roleAssignmentType": { "type": "object", "properties": { "name": { "type": "string", "nullable": true, "metadata": { - "description": "Optional. The name of the private DNS zone group config." + "description": "Optional. The name (as GUID) of the role assignment. If not provided, a GUID will be generated." } }, - "privateDnsZoneResourceId": { + "roleDefinitionIdOrName": { "type": "string", "metadata": { - "description": "Required. The resource id of the private DNS zone." + "description": "Required. The role to assign. You can provide either the display name of the role definition, the role definition GUID, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"." + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." } } }, "metadata": { + "description": "An AVM-aligned type for a role assignment.", "__bicep_imported_from!": { - "sourceTemplate": "private-dns-zone-group/main.bicep" + "sourceTemplate": "br:mcr.microsoft.com/bicep/avm/utl/types/avm-common-types:0.5.1" } } } @@ -1048,6 +1125,9 @@ }, "applicationSecurityGroupResourceIds": { "type": "array", + "items": { + "type": "string" + }, "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." @@ -1061,7 +1141,11 @@ } }, "ipConfigurations": { - "$ref": "#/definitions/ipConfigurationsType", + "type": "array", + "items": { + "$ref": "#/definitions/ipConfigurationType" + }, + "nullable": true, "metadata": { "description": "Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints." } @@ -1082,12 +1166,17 @@ }, "lock": { "$ref": "#/definitions/lockType", + "nullable": true, "metadata": { "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "$ref": "#/definitions/roleAssignmentType", + "type": "array", + "items": { + "$ref": "#/definitions/roleAssignmentType" + }, + "nullable": true, "metadata": { "description": "Optional. Array of role assignments to create." } @@ -1100,21 +1189,33 @@ } }, "customDnsConfigs": { - "$ref": "#/definitions/customDnsConfigType", + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { - "$ref": "#/definitions/manualPrivateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve connections to the remote resource. Required if `privateLinkServiceConnections` is empty." } }, "privateLinkServiceConnections": { - "$ref": "#/definitions/privateLinkServiceConnectionsType", + "type": "array", + "items": { + "$ref": "#/definitions/privateLinkServiceConnectionType" + }, + "nullable": true, "metadata": { - "description": "Optional. A grouping of information about the connection to the remote resource." + "description": "Conditional. A grouping of information about the connection to the remote resource. Required if `manualPrivateLinkServiceConnections` is empty." } }, "enableTelemetry": { @@ -1143,7 +1244,7 @@ "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + "Role Based Access Control Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" } }, "resources": { @@ -1151,7 +1252,7 @@ "condition": "[parameters('enableTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2024-03-01", - "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.7.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", + "name": "[format('46d3xbcp.res.network-privateendpoint.{0}.{1}', replace('0.10.1', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4))]", "properties": { "mode": "Incremental", "template": { @@ -1257,12 +1358,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.29.47.4906", - "templateHash": "5805178546717255803" + "version": "0.33.13.18514", + "templateHash": "5440815542537978381" }, "name": "Private Endpoint Private DNS Zone Groups", - "description": "This module deploys a Private Endpoint Private DNS Zone Group.", - "owner": "Azure/module-maintainers" + "description": "This module deploys a Private Endpoint Private DNS Zone Group." }, "definitions": { "privateDnsZoneGroupConfigType": { @@ -1340,10 +1440,7 @@ "name": "[format('{0}/{1}', parameters('privateEndpointName'), parameters('name'))]", "properties": { "privateDnsZoneConfigs": "[variables('privateDnsZoneConfigsVar')]" - }, - "dependsOn": [ - "privateEndpoint" - ] + } } }, "outputs": { @@ -1405,26 +1502,33 @@ }, "value": "[reference('privateEndpoint', '2023-11-01', 'full').location]" }, - "customDnsConfig": { - "$ref": "#/definitions/customDnsConfigType", + "customDnsConfigs": { + "type": "array", + "items": { + "$ref": "#/definitions/customDnsConfigType" + }, "metadata": { "description": "The custom DNS configurations of the private endpoint." }, "value": "[reference('privateEndpoint').customDnsConfigs]" }, - "networkInterfaceIds": { + "networkInterfaceResourceIds": { "type": "array", + "items": { + "type": "string" + }, "metadata": { - "description": "The IDs of the network interfaces associated with the private endpoint." + "description": "The resource IDs of the network interfaces associated with the private endpoint." }, - "value": "[reference('privateEndpoint').networkInterfaces]" + "value": "[map(reference('privateEndpoint').networkInterfaces, lambda('nic', lambdaVariables('nic').id))]" }, "groupId": { "type": "string", + "nullable": true, "metadata": { "description": "The group Id for the private endpoint Group." }, - "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), ''), ''))]" + "value": "[coalesce(tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'manualPrivateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0), tryGet(tryGet(tryGet(tryGet(reference('privateEndpoint'), 'privateLinkServiceConnections'), 0, 'properties'), 'groupIds'), 0))]" } } } @@ -1466,6 +1570,9 @@ }, "privateEndpoints": { "type": "array", + "items": { + "$ref": "#/definitions/privateEndpointOutputType" + }, "metadata": { "description": "The private endpoints of the private link scope." }, @@ -1474,9 +1581,9 @@ "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]" + "groupId": "[tryGet(tryGet(reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs, 'groupId'), 'value')]", + "customDnsConfigs": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.customDnsConfigs.value]", + "networkInterfaceResourceIds": "[reference(format('privateLinkScope_privateEndpoints[{0}]', copyIndex())).outputs.networkInterfaceResourceIds.value]" } } } diff --git a/avm/res/insights/private-link-scope/scoped-resource/main.json b/avm/res/insights/private-link-scope/scoped-resource/main.json index 318184f1f4..205d815637 100644 --- a/avm/res/insights/private-link-scope/scoped-resource/main.json +++ b/avm/res/insights/private-link-scope/scoped-resource/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.32.4.45862", - "templateHash": "15902182804479467110" + "version": "0.33.93.31351", + "templateHash": "18319290317274254807" }, "name": "Private Link Scope Scoped Resources", "description": "This module deploys a Private Link Scope Scoped Resource." 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 25c575033e..6d80ed1ce8 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 @@ -221,8 +221,5 @@ module testDeployment '../../../main.bicep' = [ name: 'myCustomLockName' } } - dependsOn: [ - nestedDependencies - ] } ] 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 5a537cd3fe..52c795dd51 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 @@ -175,8 +175,5 @@ module testDeployment '../../../main.bicep' = [ Role: 'DeploymentValidation' } } - dependsOn: [ - nestedDependencies - ] } ] diff --git a/avm/res/insights/private-link-scope/version.json b/avm/res/insights/private-link-scope/version.json index a8eda31021..9ed3662aba 100644 --- a/avm/res/insights/private-link-scope/version.json +++ b/avm/res/insights/private-link-scope/version.json @@ -1,7 +1,7 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.6", "pathFilters": [ "./main.json" ] -} \ No newline at end of file +}