diff --git a/bicepconfig.json b/bicepconfig.json index 6a7b736a19..9eb7e0fc3b 100644 --- a/bicepconfig.json +++ b/bicepconfig.json @@ -7,6 +7,9 @@ "rules": { "explicit-values-for-loc-params": { "level": "off" // Reason: Our modules default to e.g. the location of their parent resource group which is sufficient if deploying a self-contained solution + }, + "no-deployments-resources": { + "level": "off" // Reason: The telemetry resource only has a single output and is self-contained in a deployment } } } diff --git a/modules/app-configuration/configuration-store/.test/pe/dependencies.bicep b/modules/app-configuration/configuration-store/.test/pe/dependencies.bicep index ab851cae4a..ee93b3e1e3 100644 --- a/modules/app-configuration/configuration-store/.test/pe/dependencies.bicep +++ b/modules/app-configuration/configuration-store/.test/pe/dependencies.bicep @@ -46,4 +46,4 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/app-configuration/configuration-store/.test/pe/main.test.bicep b/modules/app-configuration/configuration-store/.test/pe/main.test.bicep index 09174e7625..9dc6bc074a 100644 --- a/modules/app-configuration/configuration-store/.test/pe/main.test.bicep +++ b/modules/app-configuration/configuration-store/.test/pe/main.test.bicep @@ -56,7 +56,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'configurationStores' diff --git a/modules/app-configuration/configuration-store/README.md b/modules/app-configuration/configuration-store/README.md index bd34bd6772..cad35ecf3a 100644 --- a/modules/app-configuration/configuration-store/README.md +++ b/modules/app-configuration/configuration-store/README.md @@ -413,7 +413,7 @@ module configurationStore 'br:bicep/modules/app-configuration.configuration-stor { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'configurationStores' @@ -469,7 +469,7 @@ module configurationStore 'br:bicep/modules/app-configuration.configuration-stor { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "configurationStores", diff --git a/modules/app-configuration/configuration-store/main.bicep b/modules/app-configuration/configuration-store/main.bicep index 30ae719fe0..4168650dca 100644 --- a/modules/app-configuration/configuration-store/main.bicep +++ b/modules/app-configuration/configuration-store/main.bicep @@ -250,14 +250,15 @@ module configurationStore_privateEndpoints '../../network/private-endpoint/main. subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/app-configuration/configuration-store/main.json b/modules/app-configuration/configuration-store/main.json index d2673179c6..fa81c86079 100644 --- a/modules/app-configuration/configuration-store/main.json +++ b/modules/app-configuration/configuration-store/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "9177345783229255097" + "templateHash": "1438402426319950203" }, "name": "App Configuration Stores", "description": "This module deploys an App Configuration Store.", @@ -648,29 +648,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -690,23 +785,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -717,11 +812,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -732,41 +834,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -775,15 +870,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -797,18 +904,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -823,33 +938,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -865,7 +1005,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -897,7 +1037,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -965,187 +1105,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1173,7 +1136,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/automation/automation-account/.test/common/main.test.bicep b/modules/automation/automation-account/.test/common/main.test.bicep index 7bfe9ab16b..5ed8331c4f 100644 --- a/modules/automation/automation-account/.test/common/main.test.bicep +++ b/modules/automation/automation-account/.test/common/main.test.bicep @@ -97,11 +97,9 @@ module testDeployment '../../main.bicep' = { ] privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'Webhook' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { @@ -111,11 +109,9 @@ module testDeployment '../../main.bicep' = { } } { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'DSCAndHybridWorker' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/automation/automation-account/README.md b/modules/automation/automation-account/README.md index 52e1318985..8e4211c951 100644 --- a/modules/automation/automation-account/README.md +++ b/modules/automation/automation-account/README.md @@ -87,11 +87,9 @@ module automationAccount 'br:bicep/modules/automation.automation-account:1.0.0' ] privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'Webhook' subnetResourceId: '' tags: { @@ -101,11 +99,9 @@ module automationAccount 'br:bicep/modules/automation.automation-account:1.0.0' } } { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'DSCAndHybridWorker' subnetResourceId: '' tags: { @@ -312,11 +308,9 @@ module automationAccount 'br:bicep/modules/automation.automation-account:1.0.0' "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "Webhook", "subnetResourceId": "", "tags": { @@ -326,11 +320,9 @@ module automationAccount 'br:bicep/modules/automation.automation-account:1.0.0' } }, { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "DSCAndHybridWorker", "subnetResourceId": "", "tags": { diff --git a/modules/automation/automation-account/main.bicep b/modules/automation/automation-account/main.bicep index 330c5c6828..3a7b1d9982 100644 --- a/modules/automation/automation-account/main.bicep +++ b/modules/automation/automation-account/main.bicep @@ -381,14 +381,15 @@ module automationAccount_privateEndpoints '../../network/private-endpoint/main.b subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/automation/automation-account/main.json b/modules/automation/automation-account/main.json index e99ac28588..0bd2c0c53d 100644 --- a/modules/automation/automation-account/main.json +++ b/modules/automation/automation-account/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "14616774767362362836" + "templateHash": "17321818753856998075" }, "name": "Automation Accounts", "description": "This module deploys an Azure Automation Account.", @@ -2019,29 +2019,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -2061,23 +2156,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -2088,11 +2183,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -2103,41 +2205,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -2146,15 +2241,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -2168,18 +2275,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -2194,33 +2309,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -2236,7 +2376,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -2268,7 +2408,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -2336,187 +2476,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2544,7 +2507,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/batch/batch-account/.test/common/main.test.bicep b/modules/batch/batch-account/.test/common/main.test.bicep index b81a0e4036..c25cddb39d 100644 --- a/modules/batch/batch-account/.test/common/main.test.bicep +++ b/modules/batch/batch-account/.test/common/main.test.bicep @@ -79,11 +79,9 @@ module testDeployment '../../main.bicep' = { { service: 'batchAccount' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] roleAssignments: [ { roleDefinitionIdOrName: 'Reader' diff --git a/modules/batch/batch-account/.test/encr/main.test.bicep b/modules/batch/batch-account/.test/encr/main.test.bicep index a19340f12a..5aebae0710 100644 --- a/modules/batch/batch-account/.test/encr/main.test.bicep +++ b/modules/batch/batch-account/.test/encr/main.test.bicep @@ -64,11 +64,9 @@ module testDeployment '../../main.bicep' = { { service: 'batchAccount' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/batch/batch-account/README.md b/modules/batch/batch-account/README.md index 17cd685691..28319537f0 100644 --- a/modules/batch/batch-account/README.md +++ b/modules/batch/batch-account/README.md @@ -59,11 +59,9 @@ module batchAccount 'br:bicep/modules/batch.batch-account:1.0.0' = { poolAllocationMode: 'BatchService' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] roleAssignments: [ { principalIds: [ @@ -138,11 +136,9 @@ module batchAccount 'br:bicep/modules/batch.batch-account:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "roleAssignments": [ { "principalIds": [ @@ -205,11 +201,9 @@ module batchAccount 'br:bicep/modules/batch.batch-account:1.0.0' = { poolAllocationMode: 'BatchService' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'batchAccount' subnetResourceId: '' tags: { @@ -268,11 +262,9 @@ module batchAccount 'br:bicep/modules/batch.batch-account:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "batchAccount", "subnetResourceId": "", "tags": { diff --git a/modules/batch/batch-account/main.bicep b/modules/batch/batch-account/main.bicep index 88fe410734..eee1855165 100644 --- a/modules/batch/batch-account/main.bicep +++ b/modules/batch/batch-account/main.bicep @@ -248,14 +248,15 @@ module batchAccount_privateEndpoints '../../network/private-endpoint/main.bicep' subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/batch/batch-account/main.json b/modules/batch/batch-account/main.json index 0253e6c50b..d169073f0f 100644 --- a/modules/batch/batch-account/main.json +++ b/modules/batch/batch-account/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "12201052807403978225" + "templateHash": "2591446309015635136" }, "name": "Batch Accounts", "description": "This module deploys a Batch Account.", @@ -375,29 +375,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -417,23 +512,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -444,11 +539,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -459,41 +561,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -502,15 +597,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -524,18 +631,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -550,33 +665,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -592,7 +732,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -624,7 +764,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -692,187 +832,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -900,7 +863,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/cache/redis-enterprise/.test/common/dependencies.bicep b/modules/cache/redis-enterprise/.test/common/dependencies.bicep index 179f4e64a2..59ae30a575 100644 --- a/modules/cache/redis-enterprise/.test/common/dependencies.bicep +++ b/modules/cache/redis-enterprise/.test/common/dependencies.bicep @@ -54,7 +54,7 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/modules/cache/redis-enterprise/.test/common/main.test.bicep b/modules/cache/redis-enterprise/.test/common/main.test.bicep index 70adc46f2c..91edd54e87 100644 --- a/modules/cache/redis-enterprise/.test/common/main.test.bicep +++ b/modules/cache/redis-enterprise/.test/common/main.test.bicep @@ -89,7 +89,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'redisEnterprise' diff --git a/modules/cache/redis-enterprise/README.md b/modules/cache/redis-enterprise/README.md index 79e8069cff..7911f628ee 100644 --- a/modules/cache/redis-enterprise/README.md +++ b/modules/cache/redis-enterprise/README.md @@ -82,7 +82,7 @@ module redisEnterprise 'br:bicep/modules/cache.redis-enterprise:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'redisEnterprise' @@ -182,7 +182,7 @@ module redisEnterprise 'br:bicep/modules/cache.redis-enterprise:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "redisEnterprise", diff --git a/modules/cache/redis-enterprise/main.bicep b/modules/cache/redis-enterprise/main.bicep index 6cd4f4da66..ea5c05e878 100644 --- a/modules/cache/redis-enterprise/main.bicep +++ b/modules/cache/redis-enterprise/main.bicep @@ -204,14 +204,15 @@ module redisCacheEnterprise_privateEndpoints '../../network/private-endpoint/mai subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/cache/redis-enterprise/main.json b/modules/cache/redis-enterprise/main.json index 0dae10b9b6..bd9889f874 100644 --- a/modules/cache/redis-enterprise/main.json +++ b/modules/cache/redis-enterprise/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "15719841187562389936" + "templateHash": "4614393026190076893" }, "name": "Redis Cache Enterprise", "description": "This module deploys a Redis Cache Enterprise.", @@ -673,29 +673,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -715,23 +810,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -742,11 +837,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -757,41 +859,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -800,15 +895,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -822,18 +929,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -848,33 +963,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -890,7 +1030,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -922,7 +1062,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -990,187 +1130,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1198,7 +1161,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/cache/redis/.test/common/dependencies.bicep b/modules/cache/redis/.test/common/dependencies.bicep index 5bb5dc56bd..bbf0956900 100644 --- a/modules/cache/redis/.test/common/dependencies.bicep +++ b/modules/cache/redis/.test/common/dependencies.bicep @@ -46,4 +46,4 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/cache/redis/.test/common/main.test.bicep b/modules/cache/redis/.test/common/main.test.bicep index 5428f2e9cb..6d7769223c 100644 --- a/modules/cache/redis/.test/common/main.test.bicep +++ b/modules/cache/redis/.test/common/main.test.bicep @@ -81,7 +81,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'redisCache' diff --git a/modules/cache/redis/README.md b/modules/cache/redis/README.md index 8360ae347a..d1de73e1b5 100644 --- a/modules/cache/redis/README.md +++ b/modules/cache/redis/README.md @@ -63,7 +63,7 @@ module redis 'br:bicep/modules/cache.redis:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'redisCache' @@ -145,7 +145,7 @@ module redis 'br:bicep/modules/cache.redis:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "redisCache", diff --git a/modules/cache/redis/main.bicep b/modules/cache/redis/main.bicep index 84350bf9bc..3794244f46 100644 --- a/modules/cache/redis/main.bicep +++ b/modules/cache/redis/main.bicep @@ -256,14 +256,15 @@ module redisCache_privateEndpoints '../../network/private-endpoint/main.bicep' = subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/cache/redis/main.json b/modules/cache/redis/main.json index d503dc74b8..04b6f51cbf 100644 --- a/modules/cache/redis/main.json +++ b/modules/cache/redis/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5929435185460509109" + "templateHash": "2042912837463951821" }, "name": "Redis Cache", "description": "This module deploys a Redis Cache.", @@ -559,29 +559,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -601,23 +696,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -628,11 +723,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -643,41 +745,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -686,15 +781,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -708,18 +815,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -734,33 +849,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -776,7 +916,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -808,7 +948,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -876,187 +1016,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1084,7 +1047,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/cognitive-services/account/.test/common/main.test.bicep b/modules/cognitive-services/account/.test/common/main.test.bicep index 39d0bbbd26..70f40c8a95 100644 --- a/modules/cognitive-services/account/.test/common/main.test.bicep +++ b/modules/cognitive-services/account/.test/common/main.test.bicep @@ -104,11 +104,9 @@ module testDeployment '../../main.bicep' = { } privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'account' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/cognitive-services/account/.test/speech/main.test.bicep b/modules/cognitive-services/account/.test/speech/main.test.bicep index 3333126f73..7bb871851f 100644 --- a/modules/cognitive-services/account/.test/speech/main.test.bicep +++ b/modules/cognitive-services/account/.test/speech/main.test.bicep @@ -53,11 +53,9 @@ module testDeployment '../../main.bicep' = { customSubDomainName: '${namePrefix}speechdomain' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'account' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/cognitive-services/account/README.md b/modules/cognitive-services/account/README.md index 1d92f15fb0..3647314693 100644 --- a/modules/cognitive-services/account/README.md +++ b/modules/cognitive-services/account/README.md @@ -75,11 +75,9 @@ module account 'br:bicep/modules/cognitive-services.account:1.0.0' = { } privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'account' subnetResourceId: '' tags: { @@ -172,11 +170,9 @@ module account 'br:bicep/modules/cognitive-services.account:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "account", "subnetResourceId": "", "tags": { @@ -374,11 +370,9 @@ module account 'br:bicep/modules/cognitive-services.account:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'account' subnetResourceId: '' tags: { @@ -431,11 +425,9 @@ module account 'br:bicep/modules/cognitive-services.account:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "account", "subnetResourceId": "", "tags": { diff --git a/modules/cognitive-services/account/main.bicep b/modules/cognitive-services/account/main.bicep index 093b347969..04f882bb27 100644 --- a/modules/cognitive-services/account/main.bicep +++ b/modules/cognitive-services/account/main.bicep @@ -291,14 +291,15 @@ module cognitiveServices_privateEndpoints '../../network/private-endpoint/main.b subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/cognitive-services/account/main.json b/modules/cognitive-services/account/main.json index cbee7b00f2..02c0c637fc 100644 --- a/modules/cognitive-services/account/main.json +++ b/modules/cognitive-services/account/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "13442875800072342008" + "templateHash": "10920180822593223575" }, "name": "Cognitive Services", "description": "This module deploys a Cognitive Service.", @@ -436,29 +436,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -478,23 +573,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -505,11 +600,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -520,41 +622,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -563,15 +658,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -585,18 +692,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -611,33 +726,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -653,7 +793,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -685,7 +825,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -753,187 +893,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -961,7 +924,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/container-registry/registry/.test/common/main.test.bicep b/modules/container-registry/registry/.test/common/main.test.bicep index 1cba142a21..0ce7c9487d 100644 --- a/modules/container-registry/registry/.test/common/main.test.bicep +++ b/modules/container-registry/registry/.test/common/main.test.bicep @@ -85,11 +85,9 @@ module testDeployment '../../main.bicep' = { { service: 'registry' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/container-registry/registry/.test/pe/main.test.bicep b/modules/container-registry/registry/.test/pe/main.test.bicep index bcb6fbfa3d..19f4dd9c96 100644 --- a/modules/container-registry/registry/.test/pe/main.test.bicep +++ b/modules/container-registry/registry/.test/pe/main.test.bicep @@ -54,11 +54,9 @@ module testDeployment '../../main.bicep' = { { service: 'registry' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/container-registry/registry/README.md b/modules/container-registry/registry/README.md index c1c5ee9a5d..e6e6561a0e 100644 --- a/modules/container-registry/registry/README.md +++ b/modules/container-registry/registry/README.md @@ -81,11 +81,9 @@ module registry 'br:bicep/modules/container-registry.registry:1.0.0' = { ] privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'registry' subnetResourceId: '' tags: { @@ -203,11 +201,9 @@ module registry 'br:bicep/modules/container-registry.registry:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "registry", "subnetResourceId": "", "tags": { @@ -429,11 +425,9 @@ module registry 'br:bicep/modules/container-registry.registry:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'registry' subnetResourceId: '' tags: { @@ -478,11 +472,9 @@ module registry 'br:bicep/modules/container-registry.registry:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "registry", "subnetResourceId": "", "tags": { diff --git a/modules/container-registry/registry/main.bicep b/modules/container-registry/registry/main.bicep index e70d4ad89d..7de517205e 100644 --- a/modules/container-registry/registry/main.bicep +++ b/modules/container-registry/registry/main.bicep @@ -382,14 +382,15 @@ module registry_privateEndpoints '../../network/private-endpoint/main.bicep' = [ subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/container-registry/registry/main.json b/modules/container-registry/registry/main.json index eb1edb3019..f718008dad 100644 --- a/modules/container-registry/registry/main.json +++ b/modules/container-registry/registry/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "810724730181048401" + "templateHash": "1580319527153380248" }, "name": "Azure Container Registries (ACR)", "description": "This module deploys an Azure Container Registry (ACR).", @@ -1164,29 +1164,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1206,23 +1301,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1233,11 +1328,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1248,41 +1350,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1291,15 +1386,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1313,18 +1420,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1339,33 +1454,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1381,7 +1521,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1413,7 +1553,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1481,187 +1621,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1689,7 +1652,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/data-factory/factory/.test/common/dependencies.bicep b/modules/data-factory/factory/.test/common/dependencies.bicep index 5c91900d1a..a6ab43ad7a 100644 --- a/modules/data-factory/factory/.test/common/dependencies.bicep +++ b/modules/data-factory/factory/.test/common/dependencies.bicep @@ -108,7 +108,7 @@ resource storageAccount 'Microsoft.Storage/storageAccounts@2021-08-01' = { output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The resource ID of the created Key Vault.') output keyVaultResourceId string = keyVault.id diff --git a/modules/data-factory/factory/.test/common/main.test.bicep b/modules/data-factory/factory/.test/common/main.test.bicep index 9d7ac74872..42da93e9d8 100644 --- a/modules/data-factory/factory/.test/common/main.test.bicep +++ b/modules/data-factory/factory/.test/common/main.test.bicep @@ -116,7 +116,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'dataFactory' diff --git a/modules/data-factory/factory/README.md b/modules/data-factory/factory/README.md index f9473fa622..c577484c79 100644 --- a/modules/data-factory/factory/README.md +++ b/modules/data-factory/factory/README.md @@ -99,7 +99,7 @@ module factory 'br:bicep/modules/data-factory.factory:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'dataFactory' @@ -225,7 +225,7 @@ module factory 'br:bicep/modules/data-factory.factory:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "dataFactory", diff --git a/modules/data-factory/factory/main.bicep b/modules/data-factory/factory/main.bicep index 14d6d25a1e..ae480b9cc8 100644 --- a/modules/data-factory/factory/main.bicep +++ b/modules/data-factory/factory/main.bicep @@ -279,14 +279,15 @@ module dataFactory_privateEndpoints '../../network/private-endpoint/main.bicep' subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/data-factory/factory/main.json b/modules/data-factory/factory/main.json index ca428834bc..dcf981878b 100644 --- a/modules/data-factory/factory/main.json +++ b/modules/data-factory/factory/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5636410891768038353" + "templateHash": "2061647637227926206" }, "name": "Data Factories", "description": "This module deploys a Data Factory.", @@ -955,29 +955,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -997,23 +1092,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1024,11 +1119,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1039,41 +1141,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1082,15 +1177,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1104,18 +1211,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1130,33 +1245,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1172,7 +1312,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1204,7 +1344,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1272,187 +1412,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1480,7 +1443,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/databricks/workspace/.test/common/dependencies.bicep b/modules/databricks/workspace/.test/common/dependencies.bicep index 7030a8aa0a..31203d82a3 100644 --- a/modules/databricks/workspace/.test/common/dependencies.bicep +++ b/modules/databricks/workspace/.test/common/dependencies.bicep @@ -312,7 +312,7 @@ output customPrivateSubnetName string = virtualNetwork.properties.subnets[2].nam output virtualNetworkResourceId string = virtualNetwork.id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The resource ID of the created Azure Machine Learning Workspace.') output machineLearningWorkspaceResourceId string = machineLearningWorkspace.id diff --git a/modules/databricks/workspace/.test/common/main.test.bicep b/modules/databricks/workspace/.test/common/main.test.bicep index cd9bef2b09..8f19bc3b68 100644 --- a/modules/databricks/workspace/.test/common/main.test.bicep +++ b/modules/databricks/workspace/.test/common/main.test.bicep @@ -120,7 +120,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'databricks_ui_api' diff --git a/modules/databricks/workspace/README.md b/modules/databricks/workspace/README.md index 79dd99e50c..cda1211cd8 100644 --- a/modules/databricks/workspace/README.md +++ b/modules/databricks/workspace/README.md @@ -80,7 +80,7 @@ module workspace 'br:bicep/modules/databricks.workspace:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'databricks_ui_api' @@ -214,7 +214,7 @@ module workspace 'br:bicep/modules/databricks.workspace:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "databricks_ui_api", diff --git a/modules/databricks/workspace/main.bicep b/modules/databricks/workspace/main.bicep index fe0ae931b5..17a6daca95 100644 --- a/modules/databricks/workspace/main.bicep +++ b/modules/databricks/workspace/main.bicep @@ -344,14 +344,15 @@ module workspace_privateEndpoints '../../network/private-endpoint/main.bicep' = subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/databricks/workspace/main.json b/modules/databricks/workspace/main.json index c729c6ec4f..2b0c724494 100644 --- a/modules/databricks/workspace/main.json +++ b/modules/databricks/workspace/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "11204795410714061974" + "templateHash": "2200640508767792289" }, "name": "Azure Databricks Workspaces", "description": "This module deploys an Azure Databricks Workspace.", @@ -567,29 +567,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -609,23 +704,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -636,11 +731,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -651,41 +753,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -694,15 +789,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -716,18 +823,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -742,33 +857,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -784,7 +924,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -816,7 +956,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -884,187 +1024,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1092,7 +1055,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/db-for-my-sql/flexible-server/.test/private/dependencies.bicep b/modules/db-for-my-sql/flexible-server/.test/private/dependencies.bicep index f3f77e9536..ca3c6ceec6 100644 --- a/modules/db-for-my-sql/flexible-server/.test/private/dependencies.bicep +++ b/modules/db-for-my-sql/flexible-server/.test/private/dependencies.bicep @@ -62,7 +62,7 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023- output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The name of the created Managed Identity.') output managedIdentityName string = managedIdentity.name diff --git a/modules/db-for-my-sql/flexible-server/.test/private/main.test.bicep b/modules/db-for-my-sql/flexible-server/.test/private/main.test.bicep index 742d0d57b6..e81954bc6b 100644 --- a/modules/db-for-my-sql/flexible-server/.test/private/main.test.bicep +++ b/modules/db-for-my-sql/flexible-server/.test/private/main.test.bicep @@ -89,7 +89,7 @@ module testDeployment '../../main.bicep' = { skuName: 'Standard_D2ds_v4' tier: 'GeneralPurpose' delegatedSubnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSResourceId + privateDnsZoneResourceId: nestedDependencies.outputs.privateDNSZoneResourceId storageAutoIoScaling: 'Enabled' storageSizeGB: 64 storageIOPS: 400 diff --git a/modules/db-for-postgre-sql/flexible-server/.test/private/dependencies.bicep b/modules/db-for-postgre-sql/flexible-server/.test/private/dependencies.bicep index 1ea4046132..45875179d8 100644 --- a/modules/db-for-postgre-sql/flexible-server/.test/private/dependencies.bicep +++ b/modules/db-for-postgre-sql/flexible-server/.test/private/dependencies.bicep @@ -62,7 +62,7 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/modules/db-for-postgre-sql/flexible-server/.test/private/main.test.bicep b/modules/db-for-postgre-sql/flexible-server/.test/private/main.test.bicep index 1852c4dffe..d5bd21da2c 100644 --- a/modules/db-for-postgre-sql/flexible-server/.test/private/main.test.bicep +++ b/modules/db-for-postgre-sql/flexible-server/.test/private/main.test.bicep @@ -100,7 +100,7 @@ module testDeployment '../../main.bicep' = { diagnosticEventHubAuthorizationRuleId: diagnosticDependencies.outputs.eventHubAuthorizationRuleId diagnosticEventHubName: diagnosticDependencies.outputs.eventHubNamespaceEventHubName geoRedundantBackup: 'Enabled' - privateDnsZoneArmResourceId: nestedDependencies.outputs.privateDNSResourceId + privateDnsZoneArmResourceId: nestedDependencies.outputs.privateDNSZoneResourceId tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/digital-twins/digital-twins-instance/.test/common/dependencies.bicep b/modules/digital-twins/digital-twins-instance/.test/common/dependencies.bicep index 997053fec3..87c0cf8a6f 100644 --- a/modules/digital-twins/digital-twins-instance/.test/common/dependencies.bicep +++ b/modules/digital-twins/digital-twins-instance/.test/common/dependencies.bicep @@ -132,7 +132,7 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id output managedIdentityPrincipalResourceId string = managedIdentity.properties.principalId @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The name of the Event Hub Namespace.') output eventhubNamespaceName string = eventHubNamespace.name diff --git a/modules/digital-twins/digital-twins-instance/.test/common/main.test.bicep b/modules/digital-twins/digital-twins-instance/.test/common/main.test.bicep index fceb1ad4b6..b9deae3ddd 100644 --- a/modules/digital-twins/digital-twins-instance/.test/common/main.test.bicep +++ b/modules/digital-twins/digital-twins-instance/.test/common/main.test.bicep @@ -99,7 +99,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'API' diff --git a/modules/digital-twins/digital-twins-instance/README.md b/modules/digital-twins/digital-twins-instance/README.md index 7c92db6dec..1f27071965 100644 --- a/modules/digital-twins/digital-twins-instance/README.md +++ b/modules/digital-twins/digital-twins-instance/README.md @@ -70,7 +70,7 @@ module digitalTwinsInstance 'br:bicep/modules/digital-twins.digital-twins-instan { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'API' @@ -158,7 +158,7 @@ module digitalTwinsInstance 'br:bicep/modules/digital-twins.digital-twins-instan { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "API", diff --git a/modules/digital-twins/digital-twins-instance/main.bicep b/modules/digital-twins/digital-twins-instance/main.bicep index de3a9f3ce7..139a665887 100644 --- a/modules/digital-twins/digital-twins-instance/main.bicep +++ b/modules/digital-twins/digital-twins-instance/main.bicep @@ -200,8 +200,9 @@ module digitalTwinsInstance_privateEndpoints '../../network/private-endpoint/mai subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] diff --git a/modules/digital-twins/digital-twins-instance/main.json b/modules/digital-twins/digital-twins-instance/main.json index 5f9ecd3472..958cae8390 100644 --- a/modules/digital-twins/digital-twins-instance/main.json +++ b/modules/digital-twins/digital-twins-instance/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "4594245496875399302" + "templateHash": "5421587631064538780" }, "name": "Digital Twins Instances", "description": "This module deploys an Azure Digital Twins Instance.", @@ -827,8 +827,9 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", @@ -836,17 +837,111 @@ }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -866,23 +961,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -893,11 +988,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -908,41 +1010,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -951,15 +1046,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -973,18 +1080,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -999,33 +1114,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1041,7 +1181,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1073,7 +1213,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1141,187 +1281,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1349,7 +1312,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/document-db/database-account/.test/sqldb/dependencies.bicep b/modules/document-db/database-account/.test/sqldb/dependencies.bicep index a360a07947..c3dd593b88 100644 --- a/modules/document-db/database-account/.test/sqldb/dependencies.bicep +++ b/modules/document-db/database-account/.test/sqldb/dependencies.bicep @@ -96,4 +96,4 @@ output managedIdentityResourceId string = managedIdentity.id output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/document-db/database-account/.test/sqldb/main.test.bicep b/modules/document-db/database-account/.test/sqldb/main.test.bicep index 8a944c41f5..c9c5272585 100644 --- a/modules/document-db/database-account/.test/sqldb/main.test.bicep +++ b/modules/document-db/database-account/.test/sqldb/main.test.bicep @@ -86,7 +86,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'Sql' diff --git a/modules/document-db/database-account/README.md b/modules/document-db/database-account/README.md index 69a8c77859..b5cad9ee10 100644 --- a/modules/document-db/database-account/README.md +++ b/modules/document-db/database-account/README.md @@ -928,7 +928,7 @@ module databaseAccount 'br:bicep/modules/document-db.database-account:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'Sql' @@ -1091,7 +1091,7 @@ module databaseAccount 'br:bicep/modules/document-db.database-account:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "Sql", diff --git a/modules/document-db/database-account/main.bicep b/modules/document-db/database-account/main.bicep index 585557fd51..2b5481b411 100644 --- a/modules/document-db/database-account/main.bicep +++ b/modules/document-db/database-account/main.bicep @@ -362,14 +362,15 @@ module databaseAccount_privateEndpoints '../../network/private-endpoint/main.bic subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/document-db/database-account/main.json b/modules/document-db/database-account/main.json index 8c6c60a55b..92692742b6 100644 --- a/modules/document-db/database-account/main.json +++ b/modules/document-db/database-account/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "1321966146332079883" + "templateHash": "14731361995400554127" }, "name": "DocumentDB Database Accounts", "description": "This module deploys a DocumentDB Database Account.", @@ -1587,29 +1587,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1629,23 +1724,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1656,11 +1751,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1671,41 +1773,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1714,15 +1809,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1736,18 +1843,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1762,33 +1877,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1804,7 +1944,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1836,7 +1976,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1904,187 +2044,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2112,7 +2075,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/event-grid/domain/.test/common/main.test.bicep b/modules/event-grid/domain/.test/common/main.test.bicep index 868878e147..1c62ba2b2b 100644 --- a/modules/event-grid/domain/.test/common/main.test.bicep +++ b/modules/event-grid/domain/.test/common/main.test.bicep @@ -80,11 +80,9 @@ module testDeployment '../../main.bicep' = { lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'domain' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/event-grid/domain/.test/pe/main.test.bicep b/modules/event-grid/domain/.test/pe/main.test.bicep index ff90a984c0..5cf831f7c2 100644 --- a/modules/event-grid/domain/.test/pe/main.test.bicep +++ b/modules/event-grid/domain/.test/pe/main.test.bicep @@ -51,11 +51,9 @@ module testDeployment '../../main.bicep' = { name: '${namePrefix}${serviceShort}001' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'domain' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/event-grid/domain/README.md b/modules/event-grid/domain/README.md index 1b981ed272..a5d51bc6c9 100644 --- a/modules/event-grid/domain/README.md +++ b/modules/event-grid/domain/README.md @@ -64,11 +64,9 @@ module domain 'br:bicep/modules/event-grid.domain:1.0.0' = { lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'domain' subnetResourceId: '' tags: { @@ -145,11 +143,9 @@ module domain 'br:bicep/modules/event-grid.domain:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "domain", "subnetResourceId": "", "tags": { @@ -254,11 +250,9 @@ module domain 'br:bicep/modules/event-grid.domain:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'domain' subnetResourceId: '' tags: { @@ -300,11 +294,9 @@ module domain 'br:bicep/modules/event-grid.domain:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "domain", "subnetResourceId": "", "tags": { diff --git a/modules/event-grid/domain/main.bicep b/modules/event-grid/domain/main.bicep index 10c4724836..fec69f3e16 100644 --- a/modules/event-grid/domain/main.bicep +++ b/modules/event-grid/domain/main.bicep @@ -169,14 +169,15 @@ module domain_privateEndpoints '../../network/private-endpoint/main.bicep' = [fo subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/event-grid/domain/main.json b/modules/event-grid/domain/main.json index dcfe142327..a9c801166c 100644 --- a/modules/event-grid/domain/main.json +++ b/modules/event-grid/domain/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "7856347884267755946" + "templateHash": "4315845252350634330" }, "name": "Event Grid Domains", "description": "This module deploys an Event Grid Domain.", @@ -399,29 +399,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -441,23 +536,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -468,11 +563,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -483,41 +585,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -526,15 +621,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -548,18 +655,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -574,33 +689,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -616,7 +756,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -648,7 +788,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -716,187 +856,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -924,7 +887,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/event-grid/topic/.test/common/main.test.bicep b/modules/event-grid/topic/.test/common/main.test.bicep index b78bcf0f8c..61bec19754 100644 --- a/modules/event-grid/topic/.test/common/main.test.bicep +++ b/modules/event-grid/topic/.test/common/main.test.bicep @@ -104,11 +104,9 @@ module testDeployment '../../main.bicep' = { lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'topic' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/event-grid/topic/.test/pe/main.test.bicep b/modules/event-grid/topic/.test/pe/main.test.bicep index 096f27cbcb..a5c992940d 100644 --- a/modules/event-grid/topic/.test/pe/main.test.bicep +++ b/modules/event-grid/topic/.test/pe/main.test.bicep @@ -51,11 +51,9 @@ module testDeployment '../../main.bicep' = { name: '${namePrefix}${serviceShort}001' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'topic' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/event-grid/topic/README.md b/modules/event-grid/topic/README.md index db0e345ab6..7987d9b586 100644 --- a/modules/event-grid/topic/README.md +++ b/modules/event-grid/topic/README.md @@ -88,11 +88,9 @@ module topic 'br:bicep/modules/event-grid.topic:1.0.0' = { lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'topic' subnetResourceId: '' tags: { @@ -192,11 +190,9 @@ module topic 'br:bicep/modules/event-grid.topic:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "topic", "subnetResourceId": "", "tags": { @@ -296,11 +292,9 @@ module topic 'br:bicep/modules/event-grid.topic:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'topic' subnetResourceId: '' tags: { @@ -342,11 +336,9 @@ module topic 'br:bicep/modules/event-grid.topic:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "topic", "subnetResourceId": "", "tags": { diff --git a/modules/event-grid/topic/main.bicep b/modules/event-grid/topic/main.bicep index 80b44ca077..2f76ab44df 100644 --- a/modules/event-grid/topic/main.bicep +++ b/modules/event-grid/topic/main.bicep @@ -171,14 +171,15 @@ module topic_privateEndpoints '../../network/private-endpoint/main.bicep' = [for subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/event-grid/topic/main.json b/modules/event-grid/topic/main.json index f60d2077df..67baf2c2eb 100644 --- a/modules/event-grid/topic/main.json +++ b/modules/event-grid/topic/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "17347618398012771479" + "templateHash": "607231381512069832" }, "name": "Event Grid Topics", "description": "This module deploys an Event Grid Topic.", @@ -476,29 +476,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -518,23 +613,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -545,11 +640,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -560,41 +662,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -603,15 +698,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -625,18 +732,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -651,33 +766,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -693,7 +833,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -725,7 +865,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -793,187 +933,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1001,7 +964,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/event-hub/namespace/.test/common/main.test.bicep b/modules/event-hub/namespace/.test/common/main.test.bicep index 9852491947..755484f15e 100644 --- a/modules/event-hub/namespace/.test/common/main.test.bicep +++ b/modules/event-hub/namespace/.test/common/main.test.bicep @@ -179,11 +179,9 @@ module testDeployment '../../main.bicep' = { } privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/event-hub/namespace/.test/pe/main.test.bicep b/modules/event-hub/namespace/.test/pe/main.test.bicep index a335175c6e..73335efe06 100644 --- a/modules/event-hub/namespace/.test/pe/main.test.bicep +++ b/modules/event-hub/namespace/.test/pe/main.test.bicep @@ -54,11 +54,9 @@ module testDeployment '../../main.bicep' = { zoneRedundant: true privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/event-hub/namespace/README.md b/modules/event-hub/namespace/README.md index de5b7fa061..1f3585e075 100644 --- a/modules/event-hub/namespace/README.md +++ b/modules/event-hub/namespace/README.md @@ -170,11 +170,9 @@ module namespace 'br:bicep/modules/event-hub.namespace:1.0.0' = { } privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'namespace' subnetResourceId: '' tags: { @@ -370,11 +368,9 @@ module namespace 'br:bicep/modules/event-hub.namespace:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "namespace", "subnetResourceId": "", "tags": { @@ -587,11 +583,9 @@ module namespace 'br:bicep/modules/event-hub.namespace:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'namespace' subnetResourceId: '' tags: { @@ -636,11 +630,9 @@ module namespace 'br:bicep/modules/event-hub.namespace:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "namespace", "subnetResourceId": "", "tags": { diff --git a/modules/event-hub/namespace/main.bicep b/modules/event-hub/namespace/main.bicep index 891c0c92d9..5c3dc8808d 100644 --- a/modules/event-hub/namespace/main.bicep +++ b/modules/event-hub/namespace/main.bicep @@ -325,14 +325,15 @@ module eventHubNamespace_privateEndpoints '../../network/private-endpoint/main.b subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/event-hub/namespace/main.json b/modules/event-hub/namespace/main.json index f95385acf9..c25cd5d3ef 100644 --- a/modules/event-hub/namespace/main.json +++ b/modules/event-hub/namespace/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "1995710596888287584" + "templateHash": "6491527792941921170" }, "name": "Event Hub Namespaces", "description": "This module deploys an Event Hub Namespace.", @@ -1609,29 +1609,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1651,23 +1746,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1678,11 +1773,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1693,41 +1795,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1736,15 +1831,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1758,18 +1865,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1784,33 +1899,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1826,7 +1966,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1858,7 +1998,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1926,187 +2066,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2134,7 +2097,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/insights/private-link-scope/.test/common/dependencies.bicep b/modules/insights/private-link-scope/.test/common/dependencies.bicep index c0529b4ac9..e09c9b5a0c 100644 --- a/modules/insights/private-link-scope/.test/common/dependencies.bicep +++ b/modules/insights/private-link-scope/.test/common/dependencies.bicep @@ -65,7 +65,7 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id output managedIdentityPrincipalId string = managedIdentity.properties.principalId @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The resource ID of the created Log Analytics Workspace.') output logAnalyticsWorkspaceResourceId string = logAnalyticsWorkspace.id diff --git a/modules/insights/private-link-scope/.test/common/main.test.bicep b/modules/insights/private-link-scope/.test/common/main.test.bicep index 9b899bd5c8..a1dcee39dc 100644 --- a/modules/insights/private-link-scope/.test/common/main.test.bicep +++ b/modules/insights/private-link-scope/.test/common/main.test.bicep @@ -64,7 +64,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'azuremonitor' diff --git a/modules/insights/private-link-scope/README.md b/modules/insights/private-link-scope/README.md index 95d6f651da..c268c5b76d 100644 --- a/modules/insights/private-link-scope/README.md +++ b/modules/insights/private-link-scope/README.md @@ -52,7 +52,7 @@ This instance deploys the module with most of its features enabled. { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'azuremonitor' @@ -113,7 +113,7 @@ This instance deploys the module with most of its features enabled. { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "azuremonitor", diff --git a/modules/insights/private-link-scope/main.bicep b/modules/insights/private-link-scope/main.bicep index 2eb0f2cdb2..578dac4911 100644 --- a/modules/insights/private-link-scope/main.bicep +++ b/modules/insights/private-link-scope/main.bicep @@ -83,14 +83,15 @@ module privateLinkScope_privateEndpoints '../../network/private-endpoint/main.bi subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/insights/private-link-scope/main.json b/modules/insights/private-link-scope/main.json index 309a70ce4d..ee38f7fe59 100644 --- a/modules/insights/private-link-scope/main.json +++ b/modules/insights/private-link-scope/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "9824068275707710634" + "templateHash": "14715354343666542323" }, "name": "Azure Monitor Private Link Scopes", "description": "This module deploys an Azure Monitor Private Link Scope.", @@ -266,29 +266,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -308,23 +403,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -335,11 +430,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -350,41 +452,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -393,15 +488,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -415,18 +522,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -441,33 +556,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -483,7 +623,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -515,7 +655,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -583,187 +723,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -791,7 +754,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/key-vault/vault/.test/common/dependencies.bicep b/modules/key-vault/vault/.test/common/dependencies.bicep index f433490224..6c3754d07f 100644 --- a/modules/key-vault/vault/.test/common/dependencies.bicep +++ b/modules/key-vault/vault/.test/common/dependencies.bicep @@ -62,4 +62,4 @@ output subnetResourceId string = virtualNetwork.properties.subnets[0].id output managedIdentityPrincipalId string = managedIdentity.properties.principalId @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/key-vault/vault/.test/common/main.test.bicep b/modules/key-vault/vault/.test/common/main.test.bicep index 179de80d30..4c17765b86 100644 --- a/modules/key-vault/vault/.test/common/main.test.bicep +++ b/modules/key-vault/vault/.test/common/main.test.bicep @@ -134,7 +134,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'vault' diff --git a/modules/key-vault/vault/.test/pe/dependencies.bicep b/modules/key-vault/vault/.test/pe/dependencies.bicep index b9eb57d972..b796986047 100644 --- a/modules/key-vault/vault/.test/pe/dependencies.bicep +++ b/modules/key-vault/vault/.test/pe/dependencies.bicep @@ -51,4 +51,4 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/key-vault/vault/.test/pe/main.test.bicep b/modules/key-vault/vault/.test/pe/main.test.bicep index 6230f07e42..2a99bb5bf2 100644 --- a/modules/key-vault/vault/.test/pe/main.test.bicep +++ b/modules/key-vault/vault/.test/pe/main.test.bicep @@ -89,7 +89,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] privateEndpointName: 'dep-${namePrefix}-pe-${serviceShort}' } diff --git a/modules/key-vault/vault/README.md b/modules/key-vault/vault/README.md index 2160f1abf6..13101ac107 100644 --- a/modules/key-vault/vault/README.md +++ b/modules/key-vault/vault/README.md @@ -292,7 +292,7 @@ module vault 'br:bicep/modules/key-vault.vault:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'vault' @@ -445,7 +445,7 @@ module vault 'br:bicep/modules/key-vault.vault:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "vault", @@ -599,7 +599,7 @@ module vault 'br:bicep/modules/key-vault.vault:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] privateEndpointName: 'dep-pe-kvvpe' } @@ -681,7 +681,7 @@ module vault 'br:bicep/modules/key-vault.vault:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ], "privateEndpointName": "dep-pe-kvvpe" }, diff --git a/modules/key-vault/vault/main.bicep b/modules/key-vault/vault/main.bicep index 08892f54ee..299ed864a3 100644 --- a/modules/key-vault/vault/main.bicep +++ b/modules/key-vault/vault/main.bicep @@ -271,14 +271,15 @@ module keyVault_privateEndpoints '../../network/private-endpoint/main.bicep' = [ subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/key-vault/vault/main.json b/modules/key-vault/vault/main.json index c270216400..18c95c024b 100644 --- a/modules/key-vault/vault/main.json +++ b/modules/key-vault/vault/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2257250292452239694" + "templateHash": "428199812087139263" }, "name": "Key Vaults", "description": "This module deploys a Key Vault.", @@ -1210,29 +1210,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1252,23 +1347,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1279,11 +1374,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1294,41 +1396,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1337,15 +1432,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1359,18 +1466,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1385,33 +1500,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1427,7 +1567,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1459,7 +1599,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1527,187 +1667,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1735,7 +1698,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/machine-learning-services/workspace/.test/common/main.test.bicep b/modules/machine-learning-services/workspace/.test/common/main.test.bicep index 1955aee361..858b81f335 100644 --- a/modules/machine-learning-services/workspace/.test/common/main.test.bicep +++ b/modules/machine-learning-services/workspace/.test/common/main.test.bicep @@ -116,11 +116,9 @@ module testDeployment '../../main.bicep' = { { service: 'amlworkspace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/machine-learning-services/workspace/.test/encr/main.test.bicep b/modules/machine-learning-services/workspace/.test/encr/main.test.bicep index 258e4cb2ec..195155da41 100644 --- a/modules/machine-learning-services/workspace/.test/encr/main.test.bicep +++ b/modules/machine-learning-services/workspace/.test/encr/main.test.bicep @@ -69,11 +69,9 @@ module testDeployment '../../main.bicep' = { { service: 'amlworkspace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/machine-learning-services/workspace/README.md b/modules/machine-learning-services/workspace/README.md index ff8b39bf37..8240128522 100644 --- a/modules/machine-learning-services/workspace/README.md +++ b/modules/machine-learning-services/workspace/README.md @@ -95,11 +95,9 @@ module workspace 'br:bicep/modules/machine-learning-services.workspace:1.0.0' = primaryUserAssignedIdentity: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'amlworkspace' subnetResourceId: '' tags: { @@ -223,11 +221,9 @@ module workspace 'br:bicep/modules/machine-learning-services.workspace:1.0.0' = "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "amlworkspace", "subnetResourceId": "", "tags": { @@ -295,11 +291,9 @@ module workspace 'br:bicep/modules/machine-learning-services.workspace:1.0.0' = primaryUserAssignedIdentity: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'amlworkspace' subnetResourceId: '' tags: { @@ -369,11 +363,9 @@ module workspace 'br:bicep/modules/machine-learning-services.workspace:1.0.0' = "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "amlworkspace", "subnetResourceId": "", "tags": { diff --git a/modules/machine-learning-services/workspace/main.bicep b/modules/machine-learning-services/workspace/main.bicep index 5aaa86fae8..afce9701f6 100644 --- a/modules/machine-learning-services/workspace/main.bicep +++ b/modules/machine-learning-services/workspace/main.bicep @@ -287,8 +287,9 @@ module workspace_privateEndpoints '../../network/private-endpoint/main.bicep' = subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] diff --git a/modules/machine-learning-services/workspace/main.json b/modules/machine-learning-services/workspace/main.json index 85a28a93ad..7d2fd747c0 100644 --- a/modules/machine-learning-services/workspace/main.json +++ b/modules/machine-learning-services/workspace/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "15135710804774691863" + "templateHash": "15631837219684432270" }, "name": "Machine Learning Services Workspaces", "description": "This module deploys a Machine Learning Services Workspace.", @@ -668,8 +668,9 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", @@ -677,17 +678,111 @@ }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -707,23 +802,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -734,11 +829,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -749,41 +851,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -792,15 +887,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -814,18 +921,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -840,33 +955,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -882,7 +1022,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -914,7 +1054,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -982,187 +1122,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1190,7 +1153,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/network/application-gateway/.test/common/main.test.bicep b/modules/network/application-gateway/.test/common/main.test.bicep index 548ada9bbd..246478d423 100644 --- a/modules/network/application-gateway/.test/common/main.test.bicep +++ b/modules/network/application-gateway/.test/common/main.test.bicep @@ -147,11 +147,9 @@ module testDeployment '../../main.bicep' = { ] privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] service: 'public' subnetResourceId: nestedDependencies.outputs.privateLinkSubnetResourceId tags: { diff --git a/modules/network/application-gateway/README.md b/modules/network/application-gateway/README.md index aaee08b326..04d88f199b 100644 --- a/modules/network/application-gateway/README.md +++ b/modules/network/application-gateway/README.md @@ -227,11 +227,9 @@ module applicationGateway 'br:bicep/modules/network.application-gateway:1.0.0' = lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'public' subnetResourceId: '' tags: { @@ -687,11 +685,9 @@ module applicationGateway 'br:bicep/modules/network.application-gateway:1.0.0' = "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "public", "subnetResourceId": "", "tags": { diff --git a/modules/network/application-gateway/main.bicep b/modules/network/application-gateway/main.bicep index a346bcf980..8d9a2f022d 100644 --- a/modules/network/application-gateway/main.bicep +++ b/modules/network/application-gateway/main.bicep @@ -376,14 +376,15 @@ module applicationGateway_privateEndpoints '../../network/private-endpoint/main. subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/network/application-gateway/main.json b/modules/network/application-gateway/main.json index c1c3844517..9856294bf1 100644 --- a/modules/network/application-gateway/main.json +++ b/modules/network/application-gateway/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "214441703213354743" + "templateHash": "9800511203053042141" }, "name": "Network Application Gateways", "description": "This module deploys a Network Application Gateway.", @@ -571,29 +571,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -613,23 +708,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -640,11 +735,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -655,41 +757,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -698,15 +793,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -720,18 +827,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -746,33 +861,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -788,7 +928,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -820,7 +960,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -888,187 +1028,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1096,7 +1059,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/network/private-endpoint/.bicep/nested_roleAssignments.bicep b/modules/network/private-endpoint/.bicep/nested_roleAssignments.bicep deleted file mode 100644 index 817cb46aa6..0000000000 --- a/modules/network/private-endpoint/.bicep/nested_roleAssignments.bicep +++ /dev/null @@ -1,97 +0,0 @@ -@sys.description('Required. The IDs of the principals to assign the role to.') -param principalIds array - -@sys.description('Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead.') -param roleDefinitionIdOrName string - -@sys.description('Required. The resource ID of the resource to apply the role assignment to.') -param resourceId string - -@sys.description('Optional. The principal type of the assigned principal ID.') -@allowed([ - 'ServicePrincipal' - 'Group' - 'User' - 'ForeignGroup' - 'Device' - '' -]) -param principalType string = '' - -@sys.description('Optional. The description of the role assignment.') -param description string = '' - -@sys.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".') -param condition string = '' - -@sys.description('Optional. Version of the condition.') -@allowed([ - '2.0' -]) -param conditionVersion string = '2.0' - -@sys.description('Optional. Id of the delegated managed identity resource.') -param delegatedManagedIdentityResourceId string = '' - -var builtInRoleNames = { - 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a') - 'Avere Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9') - 'Azure Center for SAP solutions administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7') - 'Azure Center for SAP solutions reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b') - 'Azure Center for SAP solutions service role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138') - 'Azure Kubernetes Service Policy Add-on Deployment': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064') - 'Backup Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b') - 'Backup Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324') - Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') - 'Cosmos DB Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa') - 'Desktop Virtualization Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c') - 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') - 'DNS Resolver Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d') - 'DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314') - 'DocumentDB Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450') - 'Domain Services Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2') - 'Domain Services Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb') - 'LocalNGFirewallAdministrator role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2') - 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') - 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') - 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') - 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') - 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') - 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') - 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') - 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') - Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') - 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') - Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') - 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') - 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') - 'Site Recovery Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567') - 'Site Recovery Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca') - 'SQL Managed Instance Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d') - 'SQL Security Manager': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3') - 'Storage Account Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab') - 'Traffic Manager Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7') - 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') - 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') - 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') - 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') - 'Windows Admin Center Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f') -} - -resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' existing = { - name: last(split(resourceId, '/'))! -} - -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for principalId in principalIds: { - name: guid(privateEndpoint.id, principalId, roleDefinitionIdOrName) - properties: { - description: description - roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName - principalId: principalId - principalType: !empty(principalType) ? any(principalType) : null - condition: !empty(condition) ? condition : null - conditionVersion: !empty(conditionVersion) && !empty(condition) ? conditionVersion : null - delegatedManagedIdentityResourceId: !empty(delegatedManagedIdentityResourceId) ? delegatedManagedIdentityResourceId : null - } - scope: privateEndpoint -}] diff --git a/modules/network/private-endpoint/.test/common/main.test.bicep b/modules/network/private-endpoint/.test/common/main.test.bicep index 856807277f..a33f922bd9 100644 --- a/modules/network/private-endpoint/.test/common/main.test.bicep +++ b/modules/network/private-endpoint/.test/common/main.test.bicep @@ -60,18 +60,16 @@ module testDeployment '../../main.bicep' = { ] serviceResourceId: nestedDependencies.outputs.keyVaultResourceId subnetResourceId: nestedDependencies.outputs.subnetResourceId - lock: 'CanNotDelete' - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] + lock: { + kind: 'CanNotDelete' } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] roleAssignments: [ { roleDefinitionIdOrName: 'Reader' - principalIds: [ - nestedDependencies.outputs.managedIdentityPrincipalId - ] + principalId: nestedDependencies.outputs.managedIdentityPrincipalId principalType: 'ServicePrincipal' } ] @@ -86,10 +84,8 @@ module testDeployment '../../main.bicep' = { } ] customNetworkInterfaceName: '${namePrefix}${serviceShort}001nic' - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } + applicationSecurityGroupResourceIds: [ + nestedDependencies.outputs.applicationSecurityGroupResourceId ] tags: { 'hidden-title': 'This is visible in the resource name' diff --git a/modules/network/private-endpoint/README.md b/modules/network/private-endpoint/README.md index 241b1e441a..552f6fac64 100644 --- a/modules/network/private-endpoint/README.md +++ b/modules/network/private-endpoint/README.md @@ -51,10 +51,8 @@ module privateEndpoint 'br:bicep/modules/network.private-endpoint:1.0.0' = { serviceResourceId: '' subnetResourceId: '' // Non-required parameters - applicationSecurityGroups: [ - { - id: '' - } + applicationSecurityGroupResourceIds: [ + '' ] customNetworkInterfaceName: 'npecom001nic' enableDefaultTelemetry: '' @@ -68,17 +66,15 @@ module privateEndpoint 'br:bicep/modules/network.private-endpoint:1.0.0' = { } } ] - lock: 'CanNotDelete' - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] + lock: { + kind: 'CanNotDelete' } + privateDnsZoneResourceIds: [ + '' + ] roleAssignments: [ { - principalIds: [ - '' - ] + principalId: '' principalType: 'ServicePrincipal' roleDefinitionIdOrName: 'Reader' } @@ -120,11 +116,9 @@ module privateEndpoint 'br:bicep/modules/network.private-endpoint:1.0.0' = { "value": "" }, // Non-required parameters - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "value": [ - { - "id": "" - } + "" ] }, "customNetworkInterfaceName": { @@ -146,21 +140,19 @@ module privateEndpoint 'br:bicep/modules/network.private-endpoint:1.0.0' = { ] }, "lock": { - "value": "CanNotDelete" - }, - "privateDnsZoneGroup": { "value": { - "privateDNSResourceIds": [ - "" - ] + "kind": "CanNotDelete" } }, + "privateDnsZoneResourceIds": { + "value": [ + "" + ] + }, "roleAssignments": { "value": [ { - "principalIds": [ - "" - ], + "principalId": "", "principalType": "ServicePrincipal", "roleDefinitionIdOrName": "Reader" } @@ -260,42 +252,40 @@ module privateEndpoint 'br:bicep/modules/network.private-endpoint:1.0.0' = { | Parameter | Type | Description | | :-- | :-- | :-- | -| [`applicationSecurityGroups`](#parameter-applicationsecuritygroups) | array | Application security groups in which the private endpoint IP configuration is included. | +| [`applicationSecurityGroupResourceIds`](#parameter-applicationsecuritygroupresourceids) | array | Application security groups in which the private endpoint IP configuration is included. | | [`customDnsConfigs`](#parameter-customdnsconfigs) | array | Custom DNS configurations. | | [`customNetworkInterfaceName`](#parameter-customnetworkinterfacename) | string | The custom name of the network interface attached to the private endpoint. | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable/Disable usage telemetry for module. | | [`ipConfigurations`](#parameter-ipconfigurations) | array | A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints. | | [`location`](#parameter-location) | string | Location for all Resources. | -| [`lock`](#parameter-lock) | string | Specify the type of lock. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`manualPrivateLinkServiceConnections`](#parameter-manualprivatelinkserviceconnections) | array | Manual PrivateLink Service Connections. | -| [`privateDnsZoneGroup`](#parameter-privatednszonegroup) | object | The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones. | +| [`privateDnsZoneGroupName`](#parameter-privatednszonegroupname) | string | The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. | +| [`privateDnsZoneResourceIds`](#parameter-privatednszoneresourceids) | array | The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. | | [`roleAssignments`](#parameter-roleassignments) | array | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | | [`tags`](#parameter-tags) | object | Tags to be applied on all resources/resource groups in this deployment. | -### Parameter: `applicationSecurityGroups` +### Parameter: `applicationSecurityGroupResourceIds` Application security groups in which the private endpoint IP configuration is included. - Required: No - Type: array -- Default: `[]` ### Parameter: `customDnsConfigs` Custom DNS configurations. - Required: No - Type: array -- Default: `[]` ### Parameter: `customNetworkInterfaceName` The custom name of the network interface attached to the private endpoint. - Required: No - Type: string -- Default: `''` ### Parameter: `enableDefaultTelemetry` -Enable telemetry via a Globally Unique Identifier (GUID). +Enable/Disable usage telemetry for module. - Required: No - Type: bool - Default: `True` @@ -311,7 +301,6 @@ Subtype(s) of the connection to be created. The allowed values depend on the typ 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 -- Default: `[]` ### Parameter: `location` @@ -322,18 +311,36 @@ Location for all Resources. ### Parameter: `lock` -Specify the type of lock. +The lock settings of the service. +- Required: No +- Type: object + + +| Name | Required | Type | Description | +| :-- | :-- | :--| :-- | +| [`kind`](#parameter-lockkind) | No | string | Optional. Specify the type of lock. | +| [`name`](#parameter-lockname) | No | string | Optional. Specify the name of lock. | + +### Parameter: `lock.kind` + +Optional. Specify the type of lock. + +- Required: No +- Type: string +- Allowed: `[CanNotDelete, None, ReadOnly]` + +### Parameter: `lock.name` + +Optional. Specify the name of lock. + - Required: No - Type: string -- Default: `''` -- Allowed: `['', CanNotDelete, ReadOnly]` ### Parameter: `manualPrivateLinkServiceConnections` Manual PrivateLink Service Connections. - Required: No - Type: array -- Default: `[]` ### Parameter: `name` @@ -341,19 +348,85 @@ Name of the private endpoint resource to create. - Required: Yes - Type: string -### Parameter: `privateDnsZoneGroup` +### Parameter: `privateDnsZoneGroupName` -The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones. +The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided. - Required: No -- Type: object -- Default: `{object}` +- Type: string + +### Parameter: `privateDnsZoneResourceIds` + +The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones. +- Required: No +- Type: array ### Parameter: `roleAssignments` Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. - Required: No - Type: array -- Default: `[]` + + +| Name | Required | Type | Description | +| :-- | :-- | :--| :-- | +| [`condition`](#parameter-roleassignmentscondition) | No | string | 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`](#parameter-roleassignmentsconditionversion) | No | string | Optional. Version of the condition. | +| [`delegatedManagedIdentityResourceId`](#parameter-roleassignmentsdelegatedmanagedidentityresourceid) | No | string | Optional. The Resource Id of the delegated managed identity resource. | +| [`description`](#parameter-roleassignmentsdescription) | No | string | Optional. The description of the role assignment. | +| [`principalId`](#parameter-roleassignmentsprincipalid) | Yes | string | Required. The principal ID of the principal (user/group/identity) to assign the role to. | +| [`principalType`](#parameter-roleassignmentsprincipaltype) | No | string | Optional. The principal type of the assigned principal ID. | +| [`roleDefinitionIdOrName`](#parameter-roleassignmentsroledefinitionidorname) | Yes | string | Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead. | + +### Parameter: `roleAssignments.condition` + +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" + +- Required: No +- Type: string + +### Parameter: `roleAssignments.conditionVersion` + +Optional. Version of the condition. + +- Required: No +- Type: string +- Allowed: `[2.0]` + +### Parameter: `roleAssignments.delegatedManagedIdentityResourceId` + +Optional. The Resource Id of the delegated managed identity resource. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.description` + +Optional. The description of the role assignment. + +- Required: No +- Type: string + +### Parameter: `roleAssignments.principalId` + +Required. The principal ID of the principal (user/group/identity) to assign the role to. + +- Required: Yes +- Type: string + +### Parameter: `roleAssignments.principalType` + +Optional. The principal type of the assigned principal ID. + +- Required: No +- Type: string +- Allowed: `[Device, ForeignGroup, Group, ServicePrincipal, User]` + +### Parameter: `roleAssignments.roleDefinitionIdOrName` + +Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead. + +- Required: Yes +- Type: string ### Parameter: `serviceResourceId` @@ -372,7 +445,6 @@ Resource ID of the subnet where the endpoint needs to be created. Tags to be applied on all resources/resource groups in this deployment. - Required: No - Type: object -- Default: `{object}` ## Outputs diff --git a/modules/network/private-endpoint/main.bicep b/modules/network/private-endpoint/main.bicep index c47ebca698..c432aaf71e 100644 --- a/modules/network/private-endpoint/main.bicep +++ b/modules/network/private-endpoint/main.bicep @@ -12,48 +12,59 @@ param subnetResourceId string param serviceResourceId string @description('Optional. Application security groups in which the private endpoint IP configuration is included.') -param applicationSecurityGroups array = [] +param applicationSecurityGroupResourceIds array? @description('Optional. The custom name of the network interface attached to the private endpoint.') -param customNetworkInterfaceName string = '' +param customNetworkInterfaceName string? @description('Optional. A list of IP configurations of the private endpoint. This will be used to map to the First Party Service endpoints.') -param ipConfigurations array = [] +param ipConfigurations array? @description('Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to.') param groupIds array -@description('Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones.') -param privateDnsZoneGroup object = {} +@description('Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided.') +param privateDnsZoneGroupName string? + +@description('Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones.') +param privateDnsZoneResourceIds array? @description('Optional. Location for all Resources.') param location string = resourceGroup().location -@allowed([ - '' - 'CanNotDelete' - 'ReadOnly' -]) -@description('Optional. Specify the type of lock.') -param lock string = '' +@description('Optional. The lock settings of the service.') +param lock lockType @description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') -param roleAssignments array = [] +param roleAssignments roleAssignmentType @description('Optional. Tags to be applied on all resources/resource groups in this deployment.') -param tags object = {} +param tags object? @description('Optional. Custom DNS configurations.') -param customDnsConfigs array = [] +param customDnsConfigs array? @description('Optional. Manual PrivateLink Service Connections.') -param manualPrivateLinkServiceConnections array = [] +param manualPrivateLinkServiceConnections array? -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +@description('Optional. Enable/Disable usage telemetry for module.') param enableDefaultTelemetry bool = true var enableReferencedModulesTelemetry = false +var builtInRoleNames = { + Contributor: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'DNS Resolver Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d') + 'DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314') + 'Domain Services Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2') + 'Domain Services Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + Owner: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Private DNS Zone Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f') + Reader: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Role Based Access Control Administrator (Preview)': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168') +} + resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' properties: { @@ -71,11 +82,13 @@ resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { location: location tags: tags properties: { - applicationSecurityGroups: applicationSecurityGroups - customDnsConfigs: customDnsConfigs - customNetworkInterfaceName: customNetworkInterfaceName - ipConfigurations: ipConfigurations - manualPrivateLinkServiceConnections: manualPrivateLinkServiceConnections + applicationSecurityGroups: [for applicationSecurityGroupResourceId in (applicationSecurityGroupResourceIds ?? []): { + id: applicationSecurityGroupResourceId + }] + customDnsConfigs: customDnsConfigs ?? [] + customNetworkInterfaceName: customNetworkInterfaceName ?? '' + ipConfigurations: ipConfigurations ?? [] + manualPrivateLinkServiceConnections: manualPrivateLinkServiceConnections ?? [] privateLinkServiceConnections: [ { name: name @@ -88,39 +101,40 @@ resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { subnet: { id: subnetResourceId } - } } -module privateEndpoint_privateDnsZoneGroup 'private-dns-zone-group/main.bicep' = if (!empty(privateDnsZoneGroup)) { - name: '${uniqueString(deployment().name)}-PE-PrivateDnsZoneGroup' +module privateEndpoint_privateDnsZoneGroup 'private-dns-zone-group/main.bicep' = if (!empty(privateDnsZoneResourceIds)) { + name: '${uniqueString(deployment().name)}-PrivateEndpoint-PrivateDnsZoneGroup' params: { - privateDNSResourceIds: privateDnsZoneGroup.privateDNSResourceIds + name: privateDnsZoneGroupName ?? 'default' + privateDNSResourceIds: privateDnsZoneResourceIds ?? [] privateEndpointName: privateEndpoint.name enableDefaultTelemetry: enableReferencedModulesTelemetry } } -resource privateEndpoint_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock)) { - name: '${privateEndpoint.name}-${lock}-lock' +resource privateEndpoint_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' properties: { - level: any(lock) - notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' } scope: privateEndpoint } -module privateEndpoint_roleAssignments '.bicep/nested_roleAssignments.bicep' = [for (roleAssignment, index) in roleAssignments: { - name: '${uniqueString(deployment().name, location)}-PrivateEndpoint-Rbac-${index}' - params: { - description: contains(roleAssignment, 'description') ? roleAssignment.description : '' - principalIds: roleAssignment.principalIds - principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' - roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName - condition: contains(roleAssignment, 'condition') ? roleAssignment.condition : '' - delegatedManagedIdentityResourceId: contains(roleAssignment, 'delegatedManagedIdentityResourceId') ? roleAssignment.delegatedManagedIdentityResourceId : '' - resourceId: privateEndpoint.id +resource privateEndpoint_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for (roleAssignment, index) in (roleAssignments ?? []): { + name: guid(privateEndpoint.id, roleAssignment.principalId, roleAssignment.roleDefinitionIdOrName) + properties: { + roleDefinitionId: contains(builtInRoleNames, roleAssignment.roleDefinitionIdOrName) ? builtInRoleNames[roleAssignment.roleDefinitionIdOrName] : roleAssignment.roleDefinitionIdOrName + principalId: roleAssignment.principalId + description: roleAssignment.?description + principalType: roleAssignment.?principalType + condition: roleAssignment.?condition + conditionVersion: !empty(roleAssignment.?condition) ? (roleAssignment.?conditionVersion ?? '2.0') : null // Must only be set if condtion is set + delegatedManagedIdentityResourceId: roleAssignment.?delegatedManagedIdentityResourceId } + scope: privateEndpoint }] @description('The resource group the private endpoint was deployed into.') @@ -134,3 +148,38 @@ output name string = privateEndpoint.name @description('The location the resource was deployed into.') output location string = privateEndpoint.location + +// ================ // +// Definitions // +// ================ // + +type roleAssignmentType = { + @description('Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead.') + 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' | null)? + + @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 lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? diff --git a/modules/network/private-endpoint/main.json b/modules/network/private-endpoint/main.json index afc81174b1..a4b1899571 100644 --- a/modules/network/private-endpoint/main.json +++ b/modules/network/private-endpoint/main.json @@ -1,16 +1,110 @@ { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -30,23 +124,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -57,11 +151,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -72,41 +173,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -115,15 +209,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -137,18 +243,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -163,33 +277,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -205,7 +344,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -237,7 +376,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -305,187 +444,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -513,7 +475,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } \ No newline at end of file diff --git a/modules/network/private-endpoint/private-dns-zone-group/README.md b/modules/network/private-endpoint/private-dns-zone-group/README.md index 2aebf21298..d6c0e0b294 100644 --- a/modules/network/private-endpoint/private-dns-zone-group/README.md +++ b/modules/network/private-endpoint/private-dns-zone-group/README.md @@ -33,12 +33,12 @@ This module deploys a Private Endpoint Private DNS Zone Group. | Parameter | Type | Description | | :-- | :-- | :-- | -| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable/Disable usage telemetry for module. | | [`name`](#parameter-name) | string | The name of the private DNS zone group. | ### Parameter: `enableDefaultTelemetry` -Enable telemetry via a Globally Unique Identifier (GUID). +Enable/Disable usage telemetry for module. - Required: No - Type: bool - Default: `True` diff --git a/modules/network/private-endpoint/private-dns-zone-group/main.bicep b/modules/network/private-endpoint/private-dns-zone-group/main.bicep index 316f0800b6..49a089a700 100644 --- a/modules/network/private-endpoint/private-dns-zone-group/main.bicep +++ b/modules/network/private-endpoint/private-dns-zone-group/main.bicep @@ -13,9 +13,16 @@ param privateDNSResourceIds array @description('Optional. The name of the private DNS zone group.') param name string = 'default' -@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +@description('Optional. Enable/Disable usage telemetry for module.') param enableDefaultTelemetry bool = true +var privateDnsZoneConfigs = [for privateDNSResourceId in privateDNSResourceIds: { + name: last(split(privateDNSResourceId, '/'))! + properties: { + privateDnsZoneId: privateDNSResourceId + } +}] + resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name)}' properties: { @@ -28,13 +35,6 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } } -var privateDnsZoneConfigs = [for privateDNSResourceId in privateDNSResourceIds: { - name: last(split(privateDNSResourceId, '/'))! - properties: { - privateDnsZoneId: privateDNSResourceId - } -}] - resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' existing = { name: privateEndpointName } diff --git a/modules/network/private-endpoint/private-dns-zone-group/main.json b/modules/network/private-endpoint/private-dns-zone-group/main.json index a631f45296..4216fc2481 100644 --- a/modules/network/private-endpoint/private-dns-zone-group/main.json +++ b/modules/network/private-endpoint/private-dns-zone-group/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -37,7 +37,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, diff --git a/modules/network/private-endpoint/version.json b/modules/network/private-endpoint/version.json index 04a0dd1a80..7fa401bdf7 100644 --- a/modules/network/private-endpoint/version.json +++ b/modules/network/private-endpoint/version.json @@ -1,6 +1,6 @@ { "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", - "version": "0.5", + "version": "0.1", "pathFilters": [ "./main.json" ] diff --git a/modules/purview/account/main.bicep b/modules/purview/account/main.bicep index a5eedb8ff6..a28b7465fe 100644 --- a/modules/purview/account/main.bicep +++ b/modules/purview/account/main.bicep @@ -179,14 +179,15 @@ module account_privateEndpoints '../../network/private-endpoint/main.bicep' = [f subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] @@ -202,14 +203,15 @@ module portal_privateEndpoints '../../network/private-endpoint/main.bicep' = [fo subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] @@ -225,14 +227,15 @@ module blob_privateEndpoints '../../network/private-endpoint/main.bicep' = [for subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] @@ -248,14 +251,15 @@ module queue_privateEndpoints '../../network/private-endpoint/main.bicep' = [for subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] @@ -271,14 +275,15 @@ module eventHub_privateEndpoints '../../network/private-endpoint/main.bicep' = [ subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/purview/account/main.json b/modules/purview/account/main.json index 9133d24ca9..6e06abbf04 100644 --- a/modules/purview/account/main.json +++ b/modules/purview/account/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5252602419334487318" + "templateHash": "15558179031727764706" }, "name": "Purview Accounts", "description": "This module deploys a Purview Account.", @@ -300,29 +300,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('accountPrivateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('accountPrivateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('accountPrivateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -342,23 +437,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -369,11 +464,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -384,41 +486,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -427,15 +522,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -449,18 +556,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -475,33 +590,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -517,7 +657,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -549,7 +689,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -617,187 +757,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -825,7 +788,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } @@ -864,29 +827,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('portalPrivateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('portalPrivateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('portalPrivateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -906,23 +964,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -933,11 +991,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -948,41 +1013,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -991,15 +1049,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1013,18 +1083,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1039,33 +1117,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1081,7 +1184,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1113,7 +1216,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1181,199 +1284,22 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] + } + }, + "outputs": { + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the private endpoint was deployed into." + }, + "value": "[resourceGroup().name]" }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - } - ], - "outputs": { - "resourceGroupName": { - "type": "string", - "metadata": { - "description": "The resource group the private endpoint was deployed into." - }, - "value": "[resourceGroup().name]" - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the private endpoint." + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the private endpoint." }, "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" }, @@ -1389,7 +1315,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } @@ -1428,29 +1354,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('storageBlobPrivateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('storageBlobPrivateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('storageBlobPrivateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1470,23 +1491,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1497,11 +1518,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1512,41 +1540,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1555,15 +1576,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1577,18 +1610,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1603,33 +1644,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1645,7 +1711,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1677,7 +1743,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1745,187 +1811,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1953,7 +1842,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } @@ -1992,29 +1881,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('storageQueuePrivateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('storageQueuePrivateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('storageQueuePrivateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -2034,23 +2018,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -2061,11 +2045,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -2076,41 +2067,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -2119,15 +2103,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -2141,18 +2137,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -2167,33 +2171,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -2209,7 +2238,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -2241,7 +2270,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -2309,187 +2338,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2517,7 +2369,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } @@ -2556,29 +2408,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('eventHubPrivateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('eventHubPrivateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('eventHubPrivateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -2598,23 +2545,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -2625,11 +2572,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -2640,41 +2594,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -2683,15 +2630,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -2705,18 +2664,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -2731,33 +2698,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -2773,7 +2765,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -2805,7 +2797,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -2873,187 +2865,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -3081,7 +2896,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/recovery-services/vault/.test/common/dependencies.bicep b/modules/recovery-services/vault/.test/common/dependencies.bicep index e18632bb52..12b8653f54 100644 --- a/modules/recovery-services/vault/.test/common/dependencies.bicep +++ b/modules/recovery-services/vault/.test/common/dependencies.bicep @@ -60,4 +60,4 @@ output managedIdentityPrincipalId string = managedIdentity.properties.principalI output managedIdentityResourceId string = managedIdentity.id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/recovery-services/vault/.test/common/main.test.bicep b/modules/recovery-services/vault/.test/common/main.test.bicep index aa714983ad..3f19289ce8 100644 --- a/modules/recovery-services/vault/.test/common/main.test.bicep +++ b/modules/recovery-services/vault/.test/common/main.test.bicep @@ -321,7 +321,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'AzureSiteRecovery' diff --git a/modules/recovery-services/vault/README.md b/modules/recovery-services/vault/README.md index c7bbaa77ff..0c6de6ac3a 100644 --- a/modules/recovery-services/vault/README.md +++ b/modules/recovery-services/vault/README.md @@ -315,7 +315,7 @@ module vault 'br:bicep/modules/recovery-services.vault:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'AzureSiteRecovery' @@ -651,7 +651,7 @@ module vault 'br:bicep/modules/recovery-services.vault:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "AzureSiteRecovery", diff --git a/modules/recovery-services/vault/main.bicep b/modules/recovery-services/vault/main.bicep index 5a7a9bdaf3..ec42444c6c 100644 --- a/modules/recovery-services/vault/main.bicep +++ b/modules/recovery-services/vault/main.bicep @@ -295,14 +295,15 @@ module rsv_privateEndpoints '../../network/private-endpoint/main.bicep' = [for ( subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/recovery-services/vault/main.json b/modules/recovery-services/vault/main.json index 8a77b1b8fe..e8468c9338 100644 --- a/modules/recovery-services/vault/main.json +++ b/modules/recovery-services/vault/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "9931998458625198588" + "templateHash": "1948691212198738102" }, "name": "Recovery Services Vaults", "description": "This module deploys a Recovery Services Vault.", @@ -1904,29 +1904,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1946,23 +2041,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1973,11 +2068,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1988,41 +2090,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -2031,15 +2126,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -2053,18 +2160,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -2079,33 +2194,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -2121,7 +2261,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -2153,7 +2293,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -2221,187 +2361,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2429,7 +2392,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/relay/namespace/.test/common/main.test.bicep b/modules/relay/namespace/.test/common/main.test.bicep index 219a764842..a08444f919 100644 --- a/modules/relay/namespace/.test/common/main.test.bicep +++ b/modules/relay/namespace/.test/common/main.test.bicep @@ -160,11 +160,9 @@ module testDeployment '../../main.bicep' = { { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/relay/namespace/.test/pe/main.test.bicep b/modules/relay/namespace/.test/pe/main.test.bicep index a2d978e556..30ac3bfaba 100644 --- a/modules/relay/namespace/.test/pe/main.test.bicep +++ b/modules/relay/namespace/.test/pe/main.test.bicep @@ -54,11 +54,9 @@ module testDeployment '../../main.bicep' = { { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/relay/namespace/README.md b/modules/relay/namespace/README.md index f9d8f5efff..2df4924adc 100644 --- a/modules/relay/namespace/README.md +++ b/modules/relay/namespace/README.md @@ -117,11 +117,9 @@ module namespace 'br:bicep/modules/relay.namespace:1.0.0' = { } privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'namespace' subnetResourceId: '' tags: { @@ -263,11 +261,9 @@ module namespace 'br:bicep/modules/relay.namespace:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "namespace", "subnetResourceId": "", "tags": { @@ -387,11 +383,9 @@ module namespace 'br:bicep/modules/relay.namespace:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'namespace' subnetResourceId: '' tags: { @@ -434,11 +428,9 @@ module namespace 'br:bicep/modules/relay.namespace:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "namespace", "subnetResourceId": "", "tags": { diff --git a/modules/relay/namespace/main.bicep b/modules/relay/namespace/main.bicep index 58fe8148c0..f6644258f3 100644 --- a/modules/relay/namespace/main.bicep +++ b/modules/relay/namespace/main.bicep @@ -256,14 +256,15 @@ module namespace_privateEndpoints '../../network/private-endpoint/main.bicep' = subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/relay/namespace/main.json b/modules/relay/namespace/main.json index cc816b07e5..b055137299 100644 --- a/modules/relay/namespace/main.json +++ b/modules/relay/namespace/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "14563908102814128404" + "templateHash": "23772418360996492" }, "name": "Relay Namespaces", "description": "This module deploys a Relay Namespace", @@ -1538,29 +1538,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1580,23 +1675,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1607,11 +1702,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1622,41 +1724,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1665,15 +1760,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1687,18 +1794,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1713,33 +1828,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1755,7 +1895,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1787,7 +1927,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1855,187 +1995,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2063,7 +2026,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/search/search-service/.test/pe/main.test.bicep b/modules/search/search-service/.test/pe/main.test.bicep index a8e7fbd9b9..8c0b99b109 100644 --- a/modules/search/search-service/.test/pe/main.test.bicep +++ b/modules/search/search-service/.test/pe/main.test.bicep @@ -56,16 +56,12 @@ module testDeployment '../../main.bicep' = { publicNetworkAccess: 'disabled' privateEndpoints: [ { - applicationSecurityGroups: [ - { - id: nestedDependencies.outputs.applicationSecurityGroupResourceId - } + applicationSecurityGroupResourceIds: [ + nestedDependencies.outputs.applicationSecurityGroupResourceId + ] + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId ] - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } service: 'searchService' subnetResourceId: nestedDependencies.outputs.subnetResourceId tags: { diff --git a/modules/search/search-service/README.md b/modules/search/search-service/README.md index 3cc54ce756..18d24c635b 100644 --- a/modules/search/search-service/README.md +++ b/modules/search/search-service/README.md @@ -274,16 +274,12 @@ module searchService 'br:bicep/modules/search.search-service:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - applicationSecurityGroups: [ - { - id: '' - } + applicationSecurityGroupResourceIds: [ + '' + ] + privateDnsZoneResourceIds: [ + '' ] - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } service: 'searchService' subnetResourceId: '' tags: { @@ -338,16 +334,12 @@ module searchService 'br:bicep/modules/search.search-service:1.0.0' = { "privateEndpoints": { "value": [ { - "applicationSecurityGroups": [ - { - "id": "" - } + "applicationSecurityGroupResourceIds": [ + "" + ], + "privateDnsZoneResourceIds": [ + "" ], - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, "service": "searchService", "subnetResourceId": "", "tags": { diff --git a/modules/search/search-service/main.bicep b/modules/search/search-service/main.bicep index 7e6828f7ed..b0b9eba7d9 100644 --- a/modules/search/search-service/main.bicep +++ b/modules/search/search-service/main.bicep @@ -229,14 +229,15 @@ module searchService_privateEndpoints '../../network/private-endpoint/main.bicep subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/search/search-service/main.json b/modules/search/search-service/main.json index 7a348d26c6..1b70046741 100644 --- a/modules/search/search-service/main.json +++ b/modules/search/search-service/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "6550974299074570161" + "templateHash": "3190976543296510988" }, "name": "Search Services", "description": "This module deploys a Search Service.", @@ -504,29 +504,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -546,23 +641,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -573,11 +668,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -588,41 +690,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -631,15 +726,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -653,18 +760,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -679,33 +794,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -721,7 +861,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -753,7 +893,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -821,187 +961,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1029,7 +992,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/service-bus/namespace/.test/common/main.test.bicep b/modules/service-bus/namespace/.test/common/main.test.bicep index b7ffb57b2a..73f2d61db6 100644 --- a/modules/service-bus/namespace/.test/common/main.test.bicep +++ b/modules/service-bus/namespace/.test/common/main.test.bicep @@ -195,11 +195,9 @@ module testDeployment '../../main.bicep' = { { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/service-bus/namespace/.test/pe/main.test.bicep b/modules/service-bus/namespace/.test/pe/main.test.bicep index 6d1ab9dcc2..a8152faa4b 100644 --- a/modules/service-bus/namespace/.test/pe/main.test.bicep +++ b/modules/service-bus/namespace/.test/pe/main.test.bicep @@ -55,11 +55,9 @@ module testDeployment '../../main.bicep' = { { service: 'namespace' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/service-bus/namespace/README.md b/modules/service-bus/namespace/README.md index 67765a898b..b66c706fd1 100644 --- a/modules/service-bus/namespace/README.md +++ b/modules/service-bus/namespace/README.md @@ -106,11 +106,9 @@ module namespace 'br:bicep/modules/service-bus.namespace:1.0.0' = { premiumMessagingPartitions: 1 privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'namespace' subnetResourceId: '' tags: { @@ -298,11 +296,9 @@ module namespace 'br:bicep/modules/service-bus.namespace:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "namespace", "subnetResourceId": "", "tags": { @@ -673,11 +669,9 @@ module namespace 'br:bicep/modules/service-bus.namespace:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'namespace' subnetResourceId: '' tags: { @@ -721,11 +715,9 @@ module namespace 'br:bicep/modules/service-bus.namespace:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "namespace", "subnetResourceId": "", "tags": { diff --git a/modules/service-bus/namespace/main.bicep b/modules/service-bus/namespace/main.bicep index df6693bb49..2b275b2bab 100644 --- a/modules/service-bus/namespace/main.bicep +++ b/modules/service-bus/namespace/main.bicep @@ -386,14 +386,15 @@ module serviceBusNamespace_privateEndpoints '../../network/private-endpoint/main subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/service-bus/namespace/main.json b/modules/service-bus/namespace/main.json index 974d711c69..4e96afbb9d 100644 --- a/modules/service-bus/namespace/main.json +++ b/modules/service-bus/namespace/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2912791825816834309" + "templateHash": "662928290271524993" }, "name": "Service Bus Namespaces", "description": "This module deploys a Service Bus Namespace.", @@ -2143,29 +2143,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -2185,23 +2280,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -2212,11 +2307,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -2227,41 +2329,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -2270,15 +2365,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -2292,18 +2399,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -2318,33 +2433,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -2360,7 +2500,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -2392,7 +2532,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -2460,187 +2600,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2668,7 +2631,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/signal-r-service/signal-r/.test/common/dependencies.bicep b/modules/signal-r-service/signal-r/.test/common/dependencies.bicep index bb13e27479..3f02e7b5ad 100644 --- a/modules/signal-r-service/signal-r/.test/common/dependencies.bicep +++ b/modules/signal-r-service/signal-r/.test/common/dependencies.bicep @@ -56,7 +56,7 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/modules/signal-r-service/signal-r/.test/common/main.test.bicep b/modules/signal-r-service/signal-r/.test/common/main.test.bicep index 433523a64f..fe31b8c146 100644 --- a/modules/signal-r-service/signal-r/.test/common/main.test.bicep +++ b/modules/signal-r-service/signal-r/.test/common/main.test.bicep @@ -85,7 +85,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'signalr' diff --git a/modules/signal-r-service/signal-r/README.md b/modules/signal-r-service/signal-r/README.md index 3a6b8ee2c8..f802d9ca98 100644 --- a/modules/signal-r-service/signal-r/README.md +++ b/modules/signal-r-service/signal-r/README.md @@ -79,7 +79,7 @@ module signalR 'br:bicep/modules/signal-r-service.signal-r:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'signalr' @@ -180,7 +180,7 @@ module signalR 'br:bicep/modules/signal-r-service.signal-r:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "signalr", diff --git a/modules/signal-r-service/signal-r/main.bicep b/modules/signal-r-service/signal-r/main.bicep index 94f0d16b8e..f872032e37 100644 --- a/modules/signal-r-service/signal-r/main.bicep +++ b/modules/signal-r-service/signal-r/main.bicep @@ -172,14 +172,15 @@ module signalR_privateEndpoints '../../network/private-endpoint/main.bicep' = [f serviceResourceId: signalR.id subnetResourceId: privateEndpoint.subnetResourceId location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/signal-r-service/signal-r/main.json b/modules/signal-r-service/signal-r/main.json index 9936aee029..cae060bd25 100644 --- a/modules/signal-r-service/signal-r/main.json +++ b/modules/signal-r-service/signal-r/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "1694197592231434947" + "templateHash": "18228985273880895122" }, "name": "SignalR Service SignalR", "description": "This module deploys a SignalR Service SignalR.", @@ -303,29 +303,124 @@ "value": "[parameters('privateEndpoints')[copyIndex()].subnetResourceId]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -345,23 +440,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -372,11 +467,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -387,41 +489,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -430,15 +525,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -452,18 +559,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -478,33 +593,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -520,7 +660,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -552,7 +692,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -620,187 +760,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -828,7 +791,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/signal-r-service/web-pub-sub/.test/common/dependencies.bicep b/modules/signal-r-service/web-pub-sub/.test/common/dependencies.bicep index 9ce0af1118..53f60ba74f 100644 --- a/modules/signal-r-service/web-pub-sub/.test/common/dependencies.bicep +++ b/modules/signal-r-service/web-pub-sub/.test/common/dependencies.bicep @@ -56,7 +56,7 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/modules/signal-r-service/web-pub-sub/.test/common/main.test.bicep b/modules/signal-r-service/web-pub-sub/.test/common/main.test.bicep index 841d4abf2d..e43e249e61 100644 --- a/modules/signal-r-service/web-pub-sub/.test/common/main.test.bicep +++ b/modules/signal-r-service/web-pub-sub/.test/common/main.test.bicep @@ -83,7 +83,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'webpubsub' diff --git a/modules/signal-r-service/web-pub-sub/.test/pe/dependencies.bicep b/modules/signal-r-service/web-pub-sub/.test/pe/dependencies.bicep index 4570a6d4b1..7817f5a5af 100644 --- a/modules/signal-r-service/web-pub-sub/.test/pe/dependencies.bicep +++ b/modules/signal-r-service/web-pub-sub/.test/pe/dependencies.bicep @@ -48,4 +48,4 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/signal-r-service/web-pub-sub/.test/pe/main.test.bicep b/modules/signal-r-service/web-pub-sub/.test/pe/main.test.bicep index c2aaac2b49..d72345d64b 100644 --- a/modules/signal-r-service/web-pub-sub/.test/pe/main.test.bicep +++ b/modules/signal-r-service/web-pub-sub/.test/pe/main.test.bicep @@ -53,7 +53,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'webpubsub' diff --git a/modules/signal-r-service/web-pub-sub/README.md b/modules/signal-r-service/web-pub-sub/README.md index 834852ff3f..0e2c18cbaa 100644 --- a/modules/signal-r-service/web-pub-sub/README.md +++ b/modules/signal-r-service/web-pub-sub/README.md @@ -79,7 +79,7 @@ module webPubSub 'br:bicep/modules/signal-r-service.web-pub-sub:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'webpubsub' @@ -178,7 +178,7 @@ module webPubSub 'br:bicep/modules/signal-r-service.web-pub-sub:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "webpubsub", @@ -292,7 +292,7 @@ module webPubSub 'br:bicep/modules/signal-r-service.web-pub-sub:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'webpubsub' @@ -339,7 +339,7 @@ module webPubSub 'br:bicep/modules/signal-r-service.web-pub-sub:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "webpubsub", diff --git a/modules/signal-r-service/web-pub-sub/main.bicep b/modules/signal-r-service/web-pub-sub/main.bicep index 455a9fc8a2..69b0410853 100644 --- a/modules/signal-r-service/web-pub-sub/main.bicep +++ b/modules/signal-r-service/web-pub-sub/main.bicep @@ -132,14 +132,15 @@ module webPubSub_privateEndpoints '../../network/private-endpoint/main.bicep' = serviceResourceId: webPubSub.id subnetResourceId: privateEndpoint.subnetResourceId location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/signal-r-service/web-pub-sub/main.json b/modules/signal-r-service/web-pub-sub/main.json index ac949dffda..7bca5bb716 100644 --- a/modules/signal-r-service/web-pub-sub/main.json +++ b/modules/signal-r-service/web-pub-sub/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "16709379153478427185" + "templateHash": "11691998078416920042" }, "name": "SignalR Web PubSub Services", "description": "This module deploys a SignalR Web PubSub Service.", @@ -250,29 +250,124 @@ "value": "[parameters('privateEndpoints')[copyIndex()].subnetResourceId]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -292,23 +387,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -319,11 +414,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -334,41 +436,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -377,15 +472,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -399,18 +506,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -425,33 +540,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -467,7 +607,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -499,7 +639,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -567,187 +707,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -775,7 +738,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/sql/server/.test/common/dependencies.bicep b/modules/sql/server/.test/common/dependencies.bicep index 161cf4486f..5f68856202 100644 --- a/modules/sql/server/.test/common/dependencies.bicep +++ b/modules/sql/server/.test/common/dependencies.bicep @@ -99,7 +99,7 @@ output privateEndpointSubnetResourceId string = virtualNetwork.properties.subnet output serviceEndpointSubnetResourceId string = virtualNetwork.properties.subnets[1].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The URL of the created Key Vault Encryption Key.') output keyVaultEncryptionKeyUrl string = keyVault::key.properties.keyUriWithVersion diff --git a/modules/sql/server/.test/common/main.test.bicep b/modules/sql/server/.test/common/main.test.bicep index 6c3153cc5e..b0a38b0ad7 100644 --- a/modules/sql/server/.test/common/main.test.bicep +++ b/modules/sql/server/.test/common/main.test.bicep @@ -164,7 +164,7 @@ module testDeployment '../../main.bicep' = { service: 'sqlServer' privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } tags: { diff --git a/modules/sql/server/.test/pe/dependencies.bicep b/modules/sql/server/.test/pe/dependencies.bicep index f9a6790672..ef2f9239a0 100644 --- a/modules/sql/server/.test/pe/dependencies.bicep +++ b/modules/sql/server/.test/pe/dependencies.bicep @@ -47,4 +47,4 @@ resource privateDNSZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id diff --git a/modules/sql/server/.test/pe/main.test.bicep b/modules/sql/server/.test/pe/main.test.bicep index 4be390e0ab..8a638d4dd9 100644 --- a/modules/sql/server/.test/pe/main.test.bicep +++ b/modules/sql/server/.test/pe/main.test.bicep @@ -60,7 +60,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'sqlServer' diff --git a/modules/sql/server/README.md b/modules/sql/server/README.md index 36bc8f5f0a..329c07b9ff 100644 --- a/modules/sql/server/README.md +++ b/modules/sql/server/README.md @@ -181,7 +181,7 @@ module server 'br:bicep/modules/sql.server:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'sqlServer' @@ -335,7 +335,7 @@ module server 'br:bicep/modules/sql.server:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "sqlServer", @@ -434,7 +434,7 @@ module server 'br:bicep/modules/sql.server:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'sqlServer' @@ -486,7 +486,7 @@ module server 'br:bicep/modules/sql.server:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "sqlServer", diff --git a/modules/sql/server/main.bicep b/modules/sql/server/main.bicep index f41f7bbfd1..e3ade2a5f8 100644 --- a/modules/sql/server/main.bicep +++ b/modules/sql/server/main.bicep @@ -241,14 +241,15 @@ module server_privateEndpoints '../../network/private-endpoint/main.bicep' = [fo subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/sql/server/main.json b/modules/sql/server/main.json index c7b7b619ef..ce9273e1dc 100644 --- a/modules/sql/server/main.json +++ b/modules/sql/server/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "9716612519097639469" + "templateHash": "4323187915659355433" }, "name": "Azure SQL Servers", "description": "This module deploys an Azure SQL Server.", @@ -474,7 +474,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "7000207485744795208" + "templateHash": "14921090017328805601" }, "name": "SQL Server Database", "description": "This module deploys an Azure SQL Server Database.", @@ -1226,7 +1226,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "1361594412163336206" + "templateHash": "2069769222124842536" }, "name": "SQL Server Elastic Pool", "description": "This module deploys an Azure SQL Server Elastic Pool.", @@ -1454,29 +1454,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1496,23 +1591,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1523,11 +1618,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1538,41 +1640,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1581,15 +1676,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1603,18 +1710,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1629,33 +1744,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1671,7 +1811,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1703,7 +1843,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1771,187 +1911,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1979,7 +1942,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } @@ -2021,7 +1984,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "17694214441241917212" + "templateHash": "17045860485834879442" }, "name": "Azure SQL Server Firewall Rule", "description": "This module deploys an Azure SQL Server Firewall Rule.", @@ -2151,7 +2114,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "6942471200332924480" + "templateHash": "938348054010287381" }, "name": "Azure SQL Server Virtual Network Rules", "description": "This module deploys an Azure SQL Server Virtual Network Rule.", @@ -2283,7 +2246,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "13278850436753309790" + "templateHash": "6325803563225314820" }, "name": "Azure SQL Server Security Alert Policies", "description": "This module deploys an Azure SQL Server Security Alert Policy.", @@ -2454,7 +2417,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "10943798083405880032" + "templateHash": "2049927305875122003" }, "name": "Azure SQL Server Vulnerability Assessments", "description": "This module deploys an Azure SQL Server Vulnerability Assessment.", @@ -2735,7 +2698,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "1128739845456097575" + "templateHash": "17224807912051676418" }, "name": "Azure SQL Server Encryption Protector", "description": "This module deploys an Azure SQL Server Encryption Protector.", @@ -2874,4 +2837,4 @@ "value": "[reference(resourceId('Microsoft.Sql/servers', parameters('name')), '2022-05-01-preview', 'full').location]" } } -} +} \ No newline at end of file diff --git a/modules/storage/storage-account/.test/common/main.test.bicep b/modules/storage/storage-account/.test/common/main.test.bicep index 4a706b1279..fd7f6d82b4 100644 --- a/modules/storage/storage-account/.test/common/main.test.bicep +++ b/modules/storage/storage-account/.test/common/main.test.bicep @@ -79,11 +79,9 @@ module testDeployment '../../main.bicep' = { { service: 'blob' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/storage/storage-account/.test/encr/main.test.bicep b/modules/storage/storage-account/.test/encr/main.test.bicep index 70659aa8f5..8d2d24e464 100644 --- a/modules/storage/storage-account/.test/encr/main.test.bicep +++ b/modules/storage/storage-account/.test/encr/main.test.bicep @@ -62,11 +62,9 @@ module testDeployment '../../main.bicep' = { { service: 'blob' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/storage/storage-account/README.md b/modules/storage/storage-account/README.md index 257e7ecc6c..5be3a36433 100644 --- a/modules/storage/storage-account/README.md +++ b/modules/storage/storage-account/README.md @@ -208,11 +208,9 @@ module storageAccount 'br:bicep/modules/storage.storage-account:1.0.0' = { } privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'blob' subnetResourceId: '' tags: { @@ -480,11 +478,9 @@ module storageAccount 'br:bicep/modules/storage.storage-account:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "blob", "subnetResourceId": "", "tags": { @@ -620,11 +616,9 @@ module storageAccount 'br:bicep/modules/storage.storage-account:1.0.0' = { enableDefaultTelemetry: '' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'blob' subnetResourceId: '' tags: { @@ -707,11 +701,9 @@ module storageAccount 'br:bicep/modules/storage.storage-account:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "blob", "subnetResourceId": "", "tags": { diff --git a/modules/storage/storage-account/main.bicep b/modules/storage/storage-account/main.bicep index 89a565312e..e67cd0168b 100644 --- a/modules/storage/storage-account/main.bicep +++ b/modules/storage/storage-account/main.bicep @@ -351,14 +351,15 @@ module storageAccount_privateEndpoints '../../network/private-endpoint/main.bice subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/storage/storage-account/main.json b/modules/storage/storage-account/main.json index 8ffb72979b..37226f763b 100644 --- a/modules/storage/storage-account/main.json +++ b/modules/storage/storage-account/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5401777351755094753" + "templateHash": "4491569988152591675" }, "name": "Storage Accounts", "description": "This module deploys a Storage Account.", @@ -732,29 +732,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -774,23 +869,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -801,11 +896,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -816,41 +918,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -859,15 +954,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -881,18 +988,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -907,33 +1022,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -949,7 +1089,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -981,7 +1121,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1049,187 +1189,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1257,7 +1220,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/synapse/private-link-hub/.test/common/dependencies.bicep b/modules/synapse/private-link-hub/.test/common/dependencies.bicep index 8321451459..d7ca02fccb 100644 --- a/modules/synapse/private-link-hub/.test/common/dependencies.bicep +++ b/modules/synapse/private-link-hub/.test/common/dependencies.bicep @@ -68,7 +68,7 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018- output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The principal ID of the created Managed Identity.') output managedIdentityPrincipalId string = managedIdentity.properties.principalId diff --git a/modules/synapse/private-link-hub/.test/common/main.test.bicep b/modules/synapse/private-link-hub/.test/common/main.test.bicep index fd9d7be35d..d907000003 100644 --- a/modules/synapse/private-link-hub/.test/common/main.test.bicep +++ b/modules/synapse/private-link-hub/.test/common/main.test.bicep @@ -59,7 +59,7 @@ module testDeployment '../../main.bicep' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } service: 'Web' diff --git a/modules/synapse/private-link-hub/README.md b/modules/synapse/private-link-hub/README.md index 9a56960925..ddc5efb77d 100644 --- a/modules/synapse/private-link-hub/README.md +++ b/modules/synapse/private-link-hub/README.md @@ -53,7 +53,7 @@ module privateLinkHub 'br:bicep/modules/synapse.private-link-hub:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'Web' @@ -117,7 +117,7 @@ module privateLinkHub 'br:bicep/modules/synapse.private-link-hub:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "Web", diff --git a/modules/synapse/private-link-hub/main.bicep b/modules/synapse/private-link-hub/main.bicep index 6c70f61162..f377f95757 100644 --- a/modules/synapse/private-link-hub/main.bicep +++ b/modules/synapse/private-link-hub/main.bicep @@ -84,14 +84,15 @@ module privateLinkHub_privateEndpoints '../../network/private-endpoint/main.bice subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/synapse/private-link-hub/main.json b/modules/synapse/private-link-hub/main.json index 0bb44ec6f8..080b2e1d7a 100644 --- a/modules/synapse/private-link-hub/main.json +++ b/modules/synapse/private-link-hub/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "691957729768991822" + "templateHash": "11333441944276260174" }, "name": "Azure Synapse Analytics", "description": "This module deploys an Azure Synapse Analytics (Private Link Hub).", @@ -283,29 +283,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -325,23 +420,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -352,11 +447,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -367,41 +469,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -410,15 +505,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -432,18 +539,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -458,33 +573,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -500,7 +640,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -532,7 +672,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -600,187 +740,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -808,7 +771,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/synapse/workspace/.test/common/dependencies.bicep b/modules/synapse/workspace/.test/common/dependencies.bicep index c49fab5adc..52da267176 100644 --- a/modules/synapse/workspace/.test/common/dependencies.bicep +++ b/modules/synapse/workspace/.test/common/dependencies.bicep @@ -83,7 +83,7 @@ output managedIdentityResourceId string = managedIdentity.id output subnetResourceId string = virtualNetwork.properties.subnets[0].id @description('The resource ID of the created Private DNS Zone.') -output privateDNSResourceId string = privateDNSZone.id +output privateDNSZoneResourceId string = privateDNSZone.id @description('The resource ID of the created Storage Account.') output storageAccountResourceId string = storageAccount.id diff --git a/modules/synapse/workspace/.test/common/main.test.bicep b/modules/synapse/workspace/.test/common/main.test.bicep index 0791962ad8..b0c3a9f6e5 100644 --- a/modules/synapse/workspace/.test/common/main.test.bicep +++ b/modules/synapse/workspace/.test/common/main.test.bicep @@ -89,7 +89,7 @@ module testDeployment '../../main.bicep' = { service: 'SQL' privateDnsZoneGroup: { privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSResourceId + nestedDependencies.outputs.privateDNSZoneResourceId ] } tags: { diff --git a/modules/synapse/workspace/README.md b/modules/synapse/workspace/README.md index dacfa2772f..7f228e9711 100644 --- a/modules/synapse/workspace/README.md +++ b/modules/synapse/workspace/README.md @@ -84,7 +84,7 @@ module workspace 'br:bicep/modules/synapse.workspace:1.0.0' = { { privateDnsZoneGroup: { privateDNSResourceIds: [ - '' + '' ] } service: 'SQL' @@ -183,7 +183,7 @@ module workspace 'br:bicep/modules/synapse.workspace:1.0.0' = { { "privateDnsZoneGroup": { "privateDNSResourceIds": [ - "" + "" ] }, "service": "SQL", diff --git a/modules/synapse/workspace/main.bicep b/modules/synapse/workspace/main.bicep index 6dabffcafb..ec1e80bd8e 100644 --- a/modules/synapse/workspace/main.bicep +++ b/modules/synapse/workspace/main.bicep @@ -300,14 +300,15 @@ module workspace_privateEndpoints '../../network/private-endpoint/main.bicep' = subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/synapse/workspace/main.json b/modules/synapse/workspace/main.json index 0642e4d17a..3f91c6fb88 100644 --- a/modules/synapse/workspace/main.json +++ b/modules/synapse/workspace/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "14937890692678451468" + "templateHash": "14717079863067599908" }, "name": "Synapse Workspaces", "description": "This module deploys a Synapse Workspace.", @@ -836,29 +836,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -878,23 +973,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -905,11 +1000,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, + "metadata": { + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -920,41 +1022,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -963,15 +1058,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -985,18 +1092,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1011,33 +1126,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1053,7 +1193,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1085,7 +1225,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1153,187 +1293,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1361,7 +1324,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/web/site/.test/functionAppCommon/main.test.bicep b/modules/web/site/.test/functionAppCommon/main.test.bicep index 1e12bb9d94..dd5a5d4bc4 100644 --- a/modules/web/site/.test/functionAppCommon/main.test.bicep +++ b/modules/web/site/.test/functionAppCommon/main.test.bicep @@ -149,11 +149,9 @@ module testDeployment '../../main.bicep' = { { service: 'sites' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/web/site/.test/webAppCommon/main.test.bicep b/modules/web/site/.test/webAppCommon/main.test.bicep index 96c3cde865..1c2525b809 100644 --- a/modules/web/site/.test/webAppCommon/main.test.bicep +++ b/modules/web/site/.test/webAppCommon/main.test.bicep @@ -129,11 +129,9 @@ module testDeployment '../../main.bicep' = { { service: 'sites' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/web/site/README.md b/modules/web/site/README.md index 2e79002447..1e11c9249f 100644 --- a/modules/web/site/README.md +++ b/modules/web/site/README.md @@ -142,11 +142,9 @@ module site 'br:bicep/modules/web.site:1.0.0' = { lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'sites' subnetResourceId: '' tags: { @@ -309,11 +307,9 @@ module site 'br:bicep/modules/web.site:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "sites", "subnetResourceId": "", "tags": { @@ -460,11 +456,9 @@ module site 'br:bicep/modules/web.site:1.0.0' = { ] privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'sites' subnetResourceId: '' tags: { @@ -619,11 +613,9 @@ module site 'br:bicep/modules/web.site:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "sites", "subnetResourceId": "", "tags": { diff --git a/modules/web/site/main.bicep b/modules/web/site/main.bicep index f234ad2d46..68150dd4bd 100644 --- a/modules/web/site/main.bicep +++ b/modules/web/site/main.bicep @@ -419,14 +419,15 @@ module app_privateEndpoints '../../network/private-endpoint/main.bicep' = [for ( subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/web/site/main.json b/modules/web/site/main.json index af5a3ed4e0..b4f7e806bc 100644 --- a/modules/web/site/main.json +++ b/modules/web/site/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "16969766511662743845" + "templateHash": "1810314773455463979" }, "name": "Web/Function Apps", "description": "This module deploys a Web or Function App.", @@ -866,7 +866,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "14108540523970367707" + "templateHash": "10608087316287962337" }, "name": "Web/Function App Deployment Slots", "description": "This module deploys a Web or Function App Deployment Slot.", @@ -1942,8 +1942,9 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", @@ -1951,17 +1952,111 @@ }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1981,23 +2076,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -2008,11 +2103,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -2023,41 +2125,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -2066,15 +2161,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -2088,18 +2195,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -2114,33 +2229,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -2156,7 +2296,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -2188,7 +2328,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -2256,187 +2396,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -2464,7 +2427,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } @@ -2965,29 +2928,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -3007,23 +3065,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -3034,11 +3092,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -3049,41 +3114,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -3092,15 +3150,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -3114,18 +3184,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -3140,33 +3218,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -3182,7 +3285,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -3214,7 +3317,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -3282,187 +3385,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -3490,7 +3416,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/web/site/slot/main.bicep b/modules/web/site/slot/main.bicep index f6435e2a38..c915d9df01 100644 --- a/modules/web/site/slot/main.bicep +++ b/modules/web/site/slot/main.bicep @@ -347,8 +347,9 @@ module slot_privateEndpoints '../../../network/private-endpoint/main.bicep' = [f subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] diff --git a/modules/web/site/slot/main.json b/modules/web/site/slot/main.json index 4e604fd935..2201875b2b 100644 --- a/modules/web/site/slot/main.json +++ b/modules/web/site/slot/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "14108540523970367707" + "templateHash": "10608087316287962337" }, "name": "Web/Function App Deployment Slots", "description": "This module deploys a Web or Function App Deployment Slot.", @@ -1081,8 +1081,9 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", @@ -1090,17 +1091,111 @@ }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -1120,23 +1215,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -1147,11 +1242,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -1162,41 +1264,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1205,15 +1300,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1227,18 +1334,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1253,33 +1368,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1295,7 +1435,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1327,7 +1467,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1395,187 +1535,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1603,7 +1566,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/modules/web/static-site/.test/common/main.test.bicep b/modules/web/static-site/.test/common/main.test.bicep index 914204e453..1b11689d2d 100644 --- a/modules/web/static-site/.test/common/main.test.bicep +++ b/modules/web/static-site/.test/common/main.test.bicep @@ -62,11 +62,9 @@ module testDeployment '../../main.bicep' = { { service: 'staticSites' subnetResourceId: nestedDependencies.outputs.subnetResourceId - privateDnsZoneGroup: { - privateDNSResourceIds: [ - nestedDependencies.outputs.privateDNSZoneResourceId - ] - } + privateDnsZoneResourceIds: [ + nestedDependencies.outputs.privateDNSZoneResourceId + ] tags: { 'hidden-title': 'This is visible in the resource name' Environment: 'Non-Prod' diff --git a/modules/web/static-site/README.md b/modules/web/static-site/README.md index 8e0bfb8865..ec237dd4ab 100644 --- a/modules/web/static-site/README.md +++ b/modules/web/static-site/README.md @@ -67,11 +67,9 @@ module staticSite 'br:bicep/modules/web.static-site:1.0.0' = { lock: 'CanNotDelete' privateEndpoints: [ { - privateDnsZoneGroup: { - privateDNSResourceIds: [ - '' - ] - } + privateDnsZoneResourceIds: [ + '' + ] service: 'staticSites' subnetResourceId: '' tags: { @@ -154,11 +152,9 @@ module staticSite 'br:bicep/modules/web.static-site:1.0.0' = { "privateEndpoints": { "value": [ { - "privateDnsZoneGroup": { - "privateDNSResourceIds": [ - "" - ] - }, + "privateDnsZoneResourceIds": [ + "" + ], "service": "staticSites", "subnetResourceId": "", "tags": { diff --git a/modules/web/static-site/main.bicep b/modules/web/static-site/main.bicep index 1dad12c914..9ac9ab96cb 100644 --- a/modules/web/static-site/main.bicep +++ b/modules/web/static-site/main.bicep @@ -205,14 +205,15 @@ module staticSite_privateEndpoints '../../network/private-endpoint/main.bicep' = subnetResourceId: privateEndpoint.subnetResourceId enableDefaultTelemetry: enableReferencedModulesTelemetry location: contains(privateEndpoint, 'location') ? privateEndpoint.location : reference(split(privateEndpoint.subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location - lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : lock - privateDnsZoneGroup: contains(privateEndpoint, 'privateDnsZoneGroup') ? privateEndpoint.privateDnsZoneGroup : {} + lock: contains(privateEndpoint, 'lock') ? privateEndpoint.lock : null + privateDnsZoneGroupName: contains(privateEndpoint, 'privateDnsZoneGroupName') ? privateEndpoint.privateDnsZoneGroupName : 'default' + privateDnsZoneResourceIds: contains(privateEndpoint, 'privateDnsZoneResourceIds') ? privateEndpoint.privateDnsZoneResourceIds : [] roleAssignments: contains(privateEndpoint, 'roleAssignments') ? privateEndpoint.roleAssignments : [] tags: contains(privateEndpoint, 'tags') ? privateEndpoint.tags : {} manualPrivateLinkServiceConnections: contains(privateEndpoint, 'manualPrivateLinkServiceConnections') ? privateEndpoint.manualPrivateLinkServiceConnections : [] customDnsConfigs: contains(privateEndpoint, 'customDnsConfigs') ? privateEndpoint.customDnsConfigs : [] ipConfigurations: contains(privateEndpoint, 'ipConfigurations') ? privateEndpoint.ipConfigurations : [] - applicationSecurityGroups: contains(privateEndpoint, 'applicationSecurityGroups') ? privateEndpoint.applicationSecurityGroups : [] + applicationSecurityGroupResourceIds: contains(privateEndpoint, 'applicationSecurityGroupResourceIds') ? privateEndpoint.applicationSecurityGroupResourceIds : [] customNetworkInterfaceName: contains(privateEndpoint, 'customNetworkInterfaceName') ? privateEndpoint.customNetworkInterfaceName : '' } }] diff --git a/modules/web/static-site/main.json b/modules/web/static-site/main.json index b37f808c2f..5e59eef334 100644 --- a/modules/web/static-site/main.json +++ b/modules/web/static-site/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "12872096460250206815" + "templateHash": "3230698398886586988" }, "name": "Static Web Apps", "description": "This module deploys a Static Web App.", @@ -885,29 +885,124 @@ "value": "[variables('enableReferencedModulesTelemetry')]" }, "location": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'location'), createObject('value', parameters('privateEndpoints')[copyIndex()].location), createObject('value', reference(split(parameters('privateEndpoints')[copyIndex()].subnetResourceId, '/subnets/')[0], '2020-06-01', 'Full').location))]", - "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', parameters('lock')))]", - "privateDnsZoneGroup": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroup'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroup), createObject('value', createObject()))]", + "lock": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'lock'), createObject('value', parameters('privateEndpoints')[copyIndex()].lock), createObject('value', null()))]", + "privateDnsZoneGroupName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneGroupName'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneGroupName), createObject('value', 'default'))]", + "privateDnsZoneResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'privateDnsZoneResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].privateDnsZoneResourceIds), createObject('value', createArray()))]", "roleAssignments": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'roleAssignments'), createObject('value', parameters('privateEndpoints')[copyIndex()].roleAssignments), createObject('value', createArray()))]", "tags": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'tags'), createObject('value', parameters('privateEndpoints')[copyIndex()].tags), createObject('value', createObject()))]", "manualPrivateLinkServiceConnections": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'manualPrivateLinkServiceConnections'), createObject('value', parameters('privateEndpoints')[copyIndex()].manualPrivateLinkServiceConnections), createObject('value', createArray()))]", "customDnsConfigs": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customDnsConfigs'), createObject('value', parameters('privateEndpoints')[copyIndex()].customDnsConfigs), createObject('value', createArray()))]", "ipConfigurations": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'ipConfigurations'), createObject('value', parameters('privateEndpoints')[copyIndex()].ipConfigurations), createObject('value', createArray()))]", - "applicationSecurityGroups": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroups'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroups), createObject('value', createArray()))]", + "applicationSecurityGroupResourceIds": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'applicationSecurityGroupResourceIds'), createObject('value', parameters('privateEndpoints')[copyIndex()].applicationSecurityGroupResourceIds), createObject('value', createArray()))]", "customNetworkInterfaceName": "[if(contains(parameters('privateEndpoints')[copyIndex()], 'customNetworkInterfaceName'), createObject('value', parameters('privateEndpoints')[copyIndex()].customNetworkInterfaceName), createObject('value', ''))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "2884140170473394983" + "templateHash": "16178508232344722616" }, "name": "Private Endpoints", "description": "This module deploys a Private Endpoint.", "owner": "Azure/module-maintainers" }, + "definitions": { + "roleAssignmentType": { + "type": "array", + "items": { + "type": "object", + "properties": { + "roleDefinitionIdOrName": { + "type": "string", + "metadata": { + "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." + } + }, + "principalId": { + "type": "string", + "metadata": { + "description": "Required. The principal ID of the principal (user/group/identity) to assign the role to." + } + }, + "principalType": { + "type": "string", + "allowedValues": [ + "Device", + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ], + "nullable": true, + "metadata": { + "description": "Optional. The principal type of the assigned principal ID." + } + }, + "description": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The description of the role assignment." + } + }, + "condition": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The conditions on the role assignment. This limits the resources it can be assigned to. e.g.: @Resource[Microsoft.Storage/storageAccounts/blobServices/containers:ContainerName] StringEqualsIgnoreCase \"foo_storage_container\"" + } + }, + "conditionVersion": { + "type": "string", + "allowedValues": [ + "2.0" + ], + "nullable": true, + "metadata": { + "description": "Optional. Version of the condition." + } + }, + "delegatedManagedIdentityResourceId": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The Resource Id of the delegated managed identity resource." + } + } + } + }, + "nullable": true + }, + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, "parameters": { "name": { "type": "string", @@ -927,23 +1022,23 @@ "description": "Required. Resource ID of the resource that needs to be connected to the network." } }, - "applicationSecurityGroups": { + "applicationSecurityGroupResourceIds": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Application security groups in which the private endpoint IP configuration is included." } }, "customNetworkInterfaceName": { "type": "string", - "defaultValue": "", + "nullable": true, "metadata": { "description": "Optional. The custom name of the network interface attached to the private endpoint." } }, "ipConfigurations": { "type": "array", - "defaultValue": [], + "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." } @@ -954,11 +1049,18 @@ "description": "Required. Subtype(s) of the connection to be created. The allowed values depend on the type serviceResourceId refers to." } }, - "privateDnsZoneGroup": { - "type": "object", - "defaultValue": {}, + "privateDnsZoneGroupName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the private DNS zone group to create if `privateDnsZoneResourceIds` were provided." + } + }, + "privateDnsZoneResourceIds": { + "type": "array", + "nullable": true, "metadata": { - "description": "Optional. The private DNS zone group configuration used to associate the private endpoint with one or multiple private DNS zones. A DNS zone group can support up to 5 DNS zones." + "description": "Optional. The private DNS zone groups to associate the private endpoint. A DNS zone group can support up to 5 DNS zones." } }, "location": { @@ -969,41 +1071,34 @@ } }, "lock": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "", - "CanNotDelete", - "ReadOnly" - ], + "$ref": "#/definitions/lockType", "metadata": { - "description": "Optional. Specify the type of lock." + "description": "Optional. The lock settings of the service." } }, "roleAssignments": { - "type": "array", - "defaultValue": [], + "$ref": "#/definitions/roleAssignmentType", "metadata": { "description": "Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'." } }, "tags": { "type": "object", - "defaultValue": {}, + "nullable": true, "metadata": { "description": "Optional. Tags to be applied on all resources/resource groups in this deployment." } }, "customDnsConfigs": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Custom DNS configurations." } }, "manualPrivateLinkServiceConnections": { "type": "array", - "defaultValue": [], + "nullable": true, "metadata": { "description": "Optional. Manual PrivateLink Service Connections." } @@ -1012,15 +1107,27 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, "variables": { - "enableReferencedModulesTelemetry": false + "enableReferencedModulesTelemetry": false, + "builtInRoleNames": { + "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", + "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", + "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", + "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", + "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", + "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", + "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", + "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", + "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]" + } }, - "resources": [ - { + "resources": { + "defaultTelemetry": { "condition": "[parameters('enableDefaultTelemetry')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2021-04-01", @@ -1034,18 +1141,26 @@ } } }, - { + "privateEndpoint": { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", "name": "[parameters('name')]", "location": "[parameters('location')]", "tags": "[parameters('tags')]", "properties": { - "applicationSecurityGroups": "[parameters('applicationSecurityGroups')]", - "customDnsConfigs": "[parameters('customDnsConfigs')]", - "customNetworkInterfaceName": "[parameters('customNetworkInterfaceName')]", - "ipConfigurations": "[parameters('ipConfigurations')]", - "manualPrivateLinkServiceConnections": "[parameters('manualPrivateLinkServiceConnections')]", + "copy": [ + { + "name": "applicationSecurityGroups", + "count": "[length(coalesce(parameters('applicationSecurityGroupResourceIds'), createArray()))]", + "input": { + "id": "[coalesce(parameters('applicationSecurityGroupResourceIds'), createArray())[copyIndex('applicationSecurityGroups')]]" + } + } + ], + "customDnsConfigs": "[coalesce(parameters('customDnsConfigs'), createArray())]", + "customNetworkInterfaceName": "[coalesce(parameters('customNetworkInterfaceName'), '')]", + "ipConfigurations": "[coalesce(parameters('ipConfigurations'), createArray())]", + "manualPrivateLinkServiceConnections": "[coalesce(parameters('manualPrivateLinkServiceConnections'), createArray())]", "privateLinkServiceConnections": [ { "name": "[parameters('name')]", @@ -1060,33 +1175,58 @@ } } }, - { - "condition": "[not(empty(parameters('lock')))]", + "privateEndpoint_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", "type": "Microsoft.Authorization/locks", "apiVersion": "2020-05-01", "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", - "name": "[format('{0}-{1}-lock', parameters('name'), parameters('lock'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", "properties": { - "level": "[parameters('lock')]", - "notes": "[if(equals(parameters('lock'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot modify the resource or child resources.')]" + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] }, - { - "condition": "[not(empty(parameters('privateDnsZoneGroup')))]", + "privateEndpoint_roleAssignments": { + "copy": { + "name": "privateEndpoint_roleAssignments", + "count": "[length(coalesce(parameters('roleAssignments'), createArray()))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Network/privateEndpoints/{0}', parameters('name'))]", + "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId, coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "properties": { + "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName), variables('builtInRoleNames')[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName], coalesce(parameters('roleAssignments'), createArray())[copyIndex()].roleDefinitionIdOrName)]", + "principalId": "[coalesce(parameters('roleAssignments'), createArray())[copyIndex()].principalId]", + "description": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'description')]", + "principalType": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'principalType')]", + "condition": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition')]", + "conditionVersion": "[if(not(empty(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'condition'))), coalesce(tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'conditionVersion'), '2.0'), null())]", + "delegatedManagedIdentityResourceId": "[tryGet(coalesce(parameters('roleAssignments'), createArray())[copyIndex()], 'delegatedManagedIdentityResourceId')]" + }, + "dependsOn": [ + "privateEndpoint" + ] + }, + "privateEndpoint_privateDnsZoneGroup": { + "condition": "[not(empty(parameters('privateDnsZoneResourceIds')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('{0}-PE-PrivateDnsZoneGroup', uniqueString(deployment().name))]", + "name": "[format('{0}-PrivateEndpoint-PrivateDnsZoneGroup', uniqueString(deployment().name))]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "name": { + "value": "[coalesce(parameters('privateDnsZoneGroupName'), 'default')]" + }, "privateDNSResourceIds": { - "value": "[parameters('privateDnsZoneGroup').privateDNSResourceIds]" + "value": "[coalesce(parameters('privateDnsZoneResourceIds'), createArray())]" }, "privateEndpointName": { "value": "[parameters('name')]" @@ -1102,7 +1242,7 @@ "_generator": { "name": "bicep", "version": "0.22.6.54827", - "templateHash": "5610247137574346230" + "templateHash": "16391702514342252839" }, "name": "Private Endpoint Private DNS Zone Groups", "description": "This module deploys a Private Endpoint Private DNS Zone Group.", @@ -1134,7 +1274,7 @@ "type": "bool", "defaultValue": true, "metadata": { - "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + "description": "Optional. Enable/Disable usage telemetry for module." } } }, @@ -1202,187 +1342,10 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - ] - }, - { - "copy": { - "name": "privateEndpoint_roleAssignments", - "count": "[length(parameters('roleAssignments'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('{0}-PrivateEndpoint-Rbac-{1}', uniqueString(deployment().name, parameters('location')), copyIndex())]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "description": "[if(contains(parameters('roleAssignments')[copyIndex()], 'description'), createObject('value', parameters('roleAssignments')[copyIndex()].description), createObject('value', ''))]", - "principalIds": { - "value": "[parameters('roleAssignments')[copyIndex()].principalIds]" - }, - "principalType": "[if(contains(parameters('roleAssignments')[copyIndex()], 'principalType'), createObject('value', parameters('roleAssignments')[copyIndex()].principalType), createObject('value', ''))]", - "roleDefinitionIdOrName": { - "value": "[parameters('roleAssignments')[copyIndex()].roleDefinitionIdOrName]" - }, - "condition": "[if(contains(parameters('roleAssignments')[copyIndex()], 'condition'), createObject('value', parameters('roleAssignments')[copyIndex()].condition), createObject('value', ''))]", - "delegatedManagedIdentityResourceId": "[if(contains(parameters('roleAssignments')[copyIndex()], 'delegatedManagedIdentityResourceId'), createObject('value', parameters('roleAssignments')[copyIndex()].delegatedManagedIdentityResourceId), createObject('value', ''))]", - "resourceId": { - "value": "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.22.6.54827", - "templateHash": "14351187799927334028" - } - }, - "parameters": { - "principalIds": { - "type": "array", - "metadata": { - "description": "Required. The IDs of the principals to assign the role to." - } - }, - "roleDefinitionIdOrName": { - "type": "string", - "metadata": { - "description": "Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead." - } - }, - "resourceId": { - "type": "string", - "metadata": { - "description": "Required. The resource ID of the resource to apply the role assignment to." - } - }, - "principalType": { - "type": "string", - "defaultValue": "", - "allowedValues": [ - "ServicePrincipal", - "Group", - "User", - "ForeignGroup", - "Device", - "" - ], - "metadata": { - "description": "Optional. The principal type of the assigned principal ID." - } - }, - "description": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. The description of the role assignment." - } - }, - "condition": { - "type": "string", - "defaultValue": "", - "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", - "defaultValue": "2.0", - "allowedValues": [ - "2.0" - ], - "metadata": { - "description": "Optional. Version of the condition." - } - }, - "delegatedManagedIdentityResourceId": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "Optional. Id of the delegated managed identity resource." - } - } - }, - "variables": { - "builtInRoleNames": { - "Avere Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a')]", - "Avere Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9')]", - "Azure Center for SAP solutions administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7b0c7e81-271f-4c71-90bf-e30bdfdbc2f7')]", - "Azure Center for SAP solutions reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '05352d14-a920-4328-a0de-4cbe7430e26b')]", - "Azure Center for SAP solutions service role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'aabbc5dd-1af0-458b-a942-81af88f9c138')]", - "Azure Kubernetes Service Policy Add-on Deployment": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18ed5180-3e48-46fd-8541-4ea054d57064')]", - "Backup Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5e467623-bb1f-42f4-a55d-6e525e11384b')]", - "Backup Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '00c29273-979b-4161-815c-10b084fb9324')]", - "Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "Cosmos DB Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '230815da-be43-4aae-9cb4-875f7bd000aa')]", - "Desktop Virtualization Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "DevTest Labs User": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64')]", - "DNS Resolver Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '0f2ebee7-ffd4-4fc0-b3b7-664099fdad5d')]", - "DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'befefa01-2a29-4197-83a8-272ff33ce314')]", - "DocumentDB Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '5bd9cd88-fe45-4216-938b-f97437e15450')]", - "Domain Services Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2')]", - "Domain Services Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb')]", - "LocalNGFirewallAdministrator role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a8835c7d-b5cb-47fa-b6f0-65ea10ce07a2')]", - "Log Analytics Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]", - "Log Analytics Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893')]", - "Managed Application Contributor Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e')]", - "Managed Application Operator Role": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae')]", - "Managed Applications Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44')]", - "Monitoring Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa')]", - "Monitoring Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05')]", - "Network Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7')]", - "Owner": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635')]", - "Private DNS Zone Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b12aa53e-6015-4669-85d0-8515ebb3ae7f')]", - "Reader": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7')]", - "Resource Policy Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608')]", - "Role Based Access Control Administrator (Preview)": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'f58310d9-a9f6-439a-9e8d-f62e7b41a168')]", - "Site Recovery Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '6670b86e-a3f7-4917-ac9b-5d6ab1be4567')]", - "Site Recovery Operator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '494ae006-db33-4328-bf46-533a6560a3ca')]", - "SQL Managed Instance Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4939a1f6-9ae0-4e48-a1e0-f2cbe897382d')]", - "SQL Security Manager": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '056cd41c-7e88-42e1-933e-88ba6a50c9c3')]", - "Storage Account Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '17d1049b-9a84-46fb-8f53-869881c3d3ab')]", - "Traffic Manager Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a4b10055-b0c7-44c2-b00f-c7b5b3550cf7')]", - "User Access Administrator": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9')]", - "Virtual Machine Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4')]", - "Virtual Machine Contributor": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c')]", - "Virtual Machine User Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52')]", - "Windows Admin Center Administrator Login": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f')]" - } - }, - "resources": [ - { - "copy": { - "name": "roleAssignment", - "count": "[length(parameters('principalIds'))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Network/privateEndpoints/{0}', last(split(parameters('resourceId'), '/')))]", - "name": "[guid(resourceId('Microsoft.Network/privateEndpoints', last(split(parameters('resourceId'), '/'))), parameters('principalIds')[copyIndex()], parameters('roleDefinitionIdOrName'))]", - "properties": { - "description": "[parameters('description')]", - "roleDefinitionId": "[if(contains(variables('builtInRoleNames'), parameters('roleDefinitionIdOrName')), variables('builtInRoleNames')[parameters('roleDefinitionIdOrName')], parameters('roleDefinitionIdOrName'))]", - "principalId": "[parameters('principalIds')[copyIndex()]]", - "principalType": "[if(not(empty(parameters('principalType'))), parameters('principalType'), null())]", - "condition": "[if(not(empty(parameters('condition'))), parameters('condition'), null())]", - "conditionVersion": "[if(and(not(empty(parameters('conditionVersion'))), not(empty(parameters('condition')))), parameters('conditionVersion'), null())]", - "delegatedManagedIdentityResourceId": "[if(not(empty(parameters('delegatedManagedIdentityResourceId'))), parameters('delegatedManagedIdentityResourceId'), null())]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('name'))]" + "privateEndpoint" ] } - ], + }, "outputs": { "resourceGroupName": { "type": "string", @@ -1410,7 +1373,7 @@ "metadata": { "description": "The location the resource was deployed into." }, - "value": "[reference(resourceId('Microsoft.Network/privateEndpoints', parameters('name')), '2023-04-01', 'full').location]" + "value": "[reference('privateEndpoint', '2023-04-01', 'full').location]" } } } diff --git a/utilities/pipelines/sharedScripts/Get-NestedResourceList.ps1 b/utilities/pipelines/sharedScripts/Get-NestedResourceList.ps1 index 6d4eefd0f3..c00d655c9c 100644 --- a/utilities/pipelines/sharedScripts/Get-NestedResourceList.ps1 +++ b/utilities/pipelines/sharedScripts/Get-NestedResourceList.ps1 @@ -24,8 +24,19 @@ function Get-NestedResourceList { $res = @() $currLevelResources = @() + if ($TemplateFileContent.resources) { - $currLevelResources += $TemplateFileContent.resources + if ($TemplateFileContent.resources -is [System.Collections.Hashtable]) { + # With the introduction of user defined types, a compiled template's resources are not part of an ordered hashtable instead of an array. + $currLevelResources += $TemplateFileContent.resources.Keys | ForEach-Object { + $TemplateFileContent.resources[$_] + } | Where-Object { + $_.existing -ne $true + } + } else { + # Default array + $currLevelResources += $TemplateFileContent.resources + } } foreach ($resource in $currLevelResources) { $res += $resource diff --git a/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 b/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 index 3d24f83b64..13f8d4af6f 100644 --- a/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 +++ b/utilities/pipelines/sharedScripts/Set-ModuleReadMe.ps1 @@ -628,9 +628,6 @@ function Get-OrderedParametersJSON { [string[]] $RequiredParametersList = @() ) - # Load used function(s) - . (Join-Path $PSScriptRoot 'helper' 'ConvertTo-OrderedHashtable.ps1') - # [1/3] Get all parameters from the parameter object and order them recursively $orderedContentInJSONFormat = ConvertTo-OrderedHashtable -JSONInputObject $parametersJSON @@ -976,56 +973,6 @@ function ConvertTo-FormattedBicep { return $commentedBicepParams } -<# -.SYNOPSIS -Based on the provided parameter metadata, determine whether the parameter is required or not - -.DESCRIPTION -Based on the provided parameter metadata, determine whether the parameter is required or not - -.PARAMETER Parameter -The parameter metadata to analyze. - -For example: @{ - type = 'string' - metadata = @{ - description = 'Required. The name of the Public IP Address.' - } -} - -.PARAMETER TemplateFileContent -Mandatory. The template file content object to crawl data from. - -.EXAMPLE -Get-IsParameterRequired -TemplateFileContent @{ resource = @{}; ... } -Parameter @{ type = 'string'; metadata = @{ description = 'Required. The name of the Public IP Address.' } } - -Check the given parameter whether it is required. Would result into true. -#> -function Get-IsParameterRequired { - - [CmdletBinding()] - param ( - [Parameter(Mandatory = $true)] - [hashtable] $Parameter, - - [Parameter(Mandatory)] - [hashtable] $TemplateFileContent - ) - - $hasParameterNoDefault = $Parameter.Keys -notcontains 'defaultValue' - $isParameterNullable = $Parameter['nullable'] - # User defined type - $isUserDefinedType = $Parameter.Keys -contains '$ref' - $isUserDefinedTypeNullable = $Parameter.Keys -contains '$ref' ? $TemplateFileContent.definitions[(Split-Path $Parameter.'$ref' -Leaf)]['nullable'] : $false - - # Evaluation - # The parameter is required IF it - # - has no default value, - # - is not nullable - # - has no nullable user-defined type - return $hasParameterNoDefault -and -not $isParameterNullable -and -not ($isUserDefinedType -and $isUserDefinedTypeNullable) -} - <# .SYNOPSIS Generate 'Usage examples' for the ReadMe out of the parameter files currently used to test the template @@ -1085,10 +1032,6 @@ function Set-UsageExamplesSection { [string] $SectionStartIdentifier = '## Usage examples' ) - # Load used function(s) - . (Join-Path $PSScriptRoot 'Get-ModuleTestFileList.ps1') - . (Join-Path (Split-Path $PSScriptRoot -Parent) 'resourcePublish' 'Get-PrivateRegistryRepositoryName.ps1') - $brLink = Get-PrivateRegistryRepositoryName -TemplateFilePath $TemplateFilePath # Process content @@ -1621,9 +1564,6 @@ function Initialize-ReadMe { [hashtable] $TemplateFileContent ) - . (Join-Path $PSScriptRoot 'helper' 'Get-SpecsAlignedResourceName.ps1') - . (Join-Path $PSScriptRoot 'Get-NestedResourceList.ps1') - $moduleName = $TemplateFileContent.metadata.name $moduleDescription = $TemplateFileContent.metadata.description $formattedResourceType = Get-SpecsAlignedResourceName -ResourceIdentifier $FullModuleIdentifier @@ -1750,8 +1690,14 @@ function Set-ModuleReadMe { ) # Load external functions - . (Join-Path $PSScriptRoot 'helper' 'Merge-FileWithNewContent.ps1') . (Join-Path $PSScriptRoot 'Get-NestedResourceList.ps1') + . (Join-Path $PSScriptRoot 'Get-ModuleTestFileList.ps1') + . (Join-Path $PSScriptRoot 'helper' 'Merge-FileWithNewContent.ps1') + . (Join-Path $PSScriptRoot 'helper' 'Get-IsParameterRequired.ps1') + . (Join-Path $PSScriptRoot 'helper' 'Get-SpecsAlignedResourceName.ps1') + . (Join-Path $PSScriptRoot 'helper' 'ConvertTo-OrderedHashtable.ps1') + . (Join-Path (Split-Path $PSScriptRoot -Parent) 'resourcePublish' 'Get-PrivateRegistryRepositoryName.ps1') + # Check template & make full path $TemplateFilePath = Resolve-Path -Path $TemplateFilePath -ErrorAction Stop diff --git a/utilities/pipelines/sharedScripts/helper/Get-IsParameterRequired.ps1 b/utilities/pipelines/sharedScripts/helper/Get-IsParameterRequired.ps1 new file mode 100644 index 0000000000..25db0d8322 --- /dev/null +++ b/utilities/pipelines/sharedScripts/helper/Get-IsParameterRequired.ps1 @@ -0,0 +1,49 @@ +<# +.SYNOPSIS +Based on the provided parameter metadata, determine whether the parameter is required or not + +.DESCRIPTION +Based on the provided parameter metadata, determine whether the parameter is required or not + +.PARAMETER Parameter +The parameter metadata to analyze. + +For example: @{ + type = 'string' + metadata = @{ + description = 'Required. The name of the Public IP Address.' + } +} + +.PARAMETER TemplateFileContent +Mandatory. The template file content object to crawl data from. + +.EXAMPLE +Get-IsParameterRequired -TemplateFileContent @{ resource = @{}; ... } -Parameter @{ type = 'string'; metadata = @{ description = 'Required. The name of the Public IP Address.' } } + +Check the given parameter whether it is required. Would result into true. +#> +function Get-IsParameterRequired { + + [CmdletBinding()] + param ( + [Parameter(Mandatory = $true)] + [hashtable] $Parameter, + + [Parameter(Mandatory)] + [hashtable] $TemplateFileContent + ) + + $hasParameterNoDefault = $Parameter.Keys -notcontains 'defaultValue' + $isParameterNullable = $Parameter['nullable'] + # User defined type + $isUserDefinedType = $Parameter.Keys -contains '$ref' + $isUserDefinedTypeNullable = $Parameter.Keys -contains '$ref' ? $TemplateFileContent.definitions[(Split-Path $Parameter.'$ref' -Leaf)]['nullable'] : $false + + # Evaluation + # The parameter is required IF it + # - has no default value, + # - is not nullable + # - has no nullable user-defined type + return $hasParameterNoDefault -and -not $isParameterNullable -and -not ($isUserDefinedType -and $isUserDefinedTypeNullable) +} diff --git a/utilities/pipelines/staticValidation/helper/helper.psm1 b/utilities/pipelines/staticValidation/helper/helper.psm1 index 3bfd42e141..ab80fbbac0 100644 --- a/utilities/pipelines/staticValidation/helper/helper.psm1 +++ b/utilities/pipelines/staticValidation/helper/helper.psm1 @@ -7,6 +7,7 @@ $repoRootPath = (Get-Item $PSScriptRoot).Parent.Parent.Parent.Parent.FullName . (Join-Path $repoRootPath 'utilities' 'pipelines' 'sharedScripts' 'Get-ScopeOfTemplateFile.ps1') . (Join-Path $repoRootPath 'utilities' 'pipelines' 'sharedScripts' 'Get-ModuleTestFileList.ps1') . (Join-Path $repoRootPath 'utilities' 'pipelines' 'sharedScripts' 'helper' 'ConvertTo-OrderedHashtable.ps1') +. (Join-Path $repoRootPath 'utilities' 'pipelines' 'sharedScripts' 'helper' 'Get-IsParameterRequired.ps1') . (Join-Path $repoRootPath 'utilities' 'tools' 'Get-CrossReferencedModuleList.ps1') . (Join-Path $repoRootPath 'utilities' 'tools' 'helper' 'Get-PipelineFileName.ps1') diff --git a/utilities/pipelines/staticValidation/module.tests.ps1 b/utilities/pipelines/staticValidation/module.tests.ps1 index 617609b9bd..59805a7a6d 100644 --- a/utilities/pipelines/staticValidation/module.tests.ps1 +++ b/utilities/pipelines/staticValidation/module.tests.ps1 @@ -492,7 +492,7 @@ Describe 'Module tests' -Tag 'Module' { $testFileTestCases = @() $templateFile_Parameters = $templateContent.parameters $TemplateFile_AllParameterNames = $templateFile_Parameters.Keys | Sort-Object - $TemplateFile_RequiredParametersNames = ($templateFile_Parameters.Keys | Where-Object { -not $templateFile_Parameters[$_].ContainsKey('defaultValue') }) | Sort-Object + $TemplateFile_RequiredParametersNames = ($templateFile_Parameters.Keys | Where-Object { Get-IsParameterRequired -TemplateFileContent $templateContent -Parameter $templateFile_Parameters[$_] }) | Sort-Object if (Test-Path (Join-Path $moduleFolderPath '.test')) { @@ -621,10 +621,17 @@ Describe 'Module tests' -Tag 'Module' { [string] $moduleFolderName, [hashtable] $templateContent ) - if ($lock = $templateContent.parameters.lock) { - $lock.Keys | Should -Contain 'defaultValue' - $lock.defaultValue | Should -Be '' + $lock = $templateContent.parameters.lock + + if (-not $lock) { + Set-ItResult -Skipped -Because 'the module template has no lock parameter implemented' } + + $isNullable = $lock.nullable + $hasEmptyDefault = $lock.defaultValue -eq '' + $hasNullableUDT = ($lock.Keys -contains '$ref') ? $templateContent.definitions[(Split-Path $lock.'$ref' -Leaf)].nullable : $false + + ($isNullable -or $hasEmptyDefault -or $hasNullableUDT) | Should -Be $true -Because 'the lock should either have an empty default value, be nullable, or have a nullable user-defined type to not enforce locks by default' } It '[] Parameter names should be camel-cased (no dashes or underscores and must start with lower-case letter).' -TestCases $deploymentFolderTestCases { @@ -701,16 +708,22 @@ Describe 'Module tests' -Tag 'Module' { [string] $moduleFolderName, [hashtable] $templateContent ) - $enableDefaultTelemetryFlag = @() $Schemaverion = $templateContent.'$schema' if ((($Schemaverion.Split('/')[5]).Split('.')[0]) -eq (($RGdeployment.Split('/')[5]).Split('.')[0])) { - if (($templateContent.resources.type -ccontains 'Microsoft.Resources/deployments' -and $templateContent.resources.condition -like "*[parameters('enableDefaultTelemetry')]*") -or ($templateContent.resources.resources.type -ccontains 'Microsoft.Resources/deployments' -and $templateContent.resources.resources.condition -like "*[parameters('enableDefaultTelemetry')]*")) { - $enableDefaultTelemetryFlag += $true + + if ($templateContent.resources -is [hashtable]) { + # Template with User-defined-types + $templateContent.resources.Keys | Should -Contain 'defaultTelemetry' + $templateContent.resources['defaultTelemetry'].condition | Should -Be "[parameters('enableDefaultTelemetry')]" } else { - $enableDefaultTelemetryFlag += $false + # Template without User-defined-types + $telemetryDeployment = $templateContent.resources | Where-Object { + $_.type -eq 'Microsoft.Resources/deployments' -and + $_.condition -eq "[parameters('enableDefaultTelemetry')]" + } + $telemetryDeployment | Should -Not -BeNullOrEmpty } } - $enableDefaultTelemetryFlag | Should -Not -Contain $false } It '[] The Location should be defined as a parameter, with the default value of [resourceGroup().Location] or global for ResourceGroup deployment scope.' -TestCases $deploymentFolderTestCases {