From 57cce4d4c45d09385862013596c16cfcbdc4483a Mon Sep 17 00:00:00 2001 From: Jason Masten Date: Wed, 27 Nov 2024 16:14:37 -0500 Subject: [PATCH] AVD Add-On: Added marketplace terms & other fixes (#1134) * Fixed API versions for MAG * Added condition for role assignment * Fixed API version for MAG * Fixed API version for MAG * Compiled bicep changes * Moved role definitions, Fixed tags & workspace names * Fixed tags * Fixed workspace names * Moved role definitions, Fixed tags & comment * Moved role definitions; Fixed scopes, tags, & comments * Moved role definitions * Moved role definitions; Fixed tags & comments * Compiled bicep changes * Sorted params, Added marketplace terms deployment & dependency * Added missing params * Added param for session hosts deployment * Compiled bicep changes * Added new element for security groups * Added example of security principal, Updated property name for security principal * Compiled bicep changes * Fixed scopes * Fix tags, Simplified subnet resource ID * Added resources for tagging * Fixed names for app group & workspaces * Fixed tags * Fixed name for app group * Removed param * Compiled bicep changes * Fixed app group name * Added VM plan * Fixed JSON conversion * Updated role assignment for scaling plan mgmt * Moved control plane to mgmt * Moved control plane to management * Added policy & resource group; Updated deployment names; Fixed tags; Moved role assignment & function app; Updated comments * Moved mgmt step * Fixed tags * Fixed tags * Updated SKU & PS version * Moved function resource * Added function resource * Moved function app & function * Fixed resource group scope * Added condition to role assignment * Fixed VM size constraints * Updated naming changes * GitHub Action: Build Bicep to JSON --------- Co-authored-by: github-actions --- .../artifacts/Disable-Autoscale.ps1 | 6 +- .../artifacts/Set-AzureMarketplaceTerms.ps1 | 4 +- .../Set-HostPoolRegistrationToken.ps1 | 57 - .../modules/common/function.bicep | 27 - .../modules/controlPlane/controlPlane.bicep | 103 - .../fslogix/azureFiles/azureFiles.bicep | 38 +- .../modules/fslogix/fslogix.bicep | 55 +- .../azure-virtual-desktop/modules/logic.bicep | 100 - .../applicationGroup.bicep | 42 +- .../modules/management/diskAccess.bicep | 12 +- .../modules/management/functionApp.bicep | 99 +- .../hostPool.bicep | 19 +- .../modules/management/management.bicep | 268 +- .../modules/management/monitoring.bicep | 16 +- .../modules/management/policy.bicep | 3 + .../management/recoveryServicesVault.bicep | 19 +- .../modules/management/scalingPlan.bicep | 4 +- .../modules/management/virtualMachine.bicep | 17 +- .../modules/resourceGroup.bicep | 11 - .../modules/sessionHosts/sessionHosts.bicep | 114 +- .../sessionHosts/virtualMachines.bicep | 11 +- .../azure-virtual-desktop/solution.bicep | 253 +- .../azure-virtual-desktop/solution.json | 15478 ++++++++-------- .../azure-virtual-desktop/uiDefinition.json | 547 +- src/bicep/add-ons/imaging/solution.json | 257 +- src/bicep/add-ons/imaging/uiDefinition.json | 4 - src/bicep/add-ons/tier3/solution.json | 153 +- src/bicep/mlz.json | 24 +- src/bicep/modules/naming-convention.bicep | 18 +- 29 files changed, 8321 insertions(+), 9438 deletions(-) delete mode 100644 src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-HostPoolRegistrationToken.ps1 delete mode 100644 src/bicep/add-ons/azure-virtual-desktop/modules/common/function.bicep delete mode 100644 src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/controlPlane.bicep delete mode 100644 src/bicep/add-ons/azure-virtual-desktop/modules/logic.bicep rename src/bicep/add-ons/azure-virtual-desktop/modules/{controlPlane => management}/applicationGroup.bicep (51%) rename src/bicep/add-ons/azure-virtual-desktop/modules/{controlPlane => management}/hostPool.bicep (75%) delete mode 100644 src/bicep/add-ons/azure-virtual-desktop/modules/resourceGroup.bicep diff --git a/src/bicep/add-ons/azure-virtual-desktop/artifacts/Disable-Autoscale.ps1 b/src/bicep/add-ons/azure-virtual-desktop/artifacts/Disable-Autoscale.ps1 index 15d9eb3e6..2b57637bf 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/artifacts/Disable-Autoscale.ps1 +++ b/src/bicep/add-ons/azure-virtual-desktop/artifacts/Disable-Autoscale.ps1 @@ -28,14 +28,14 @@ $AzureManagementHeader = @{ $ScalingPlanExists = (Invoke-RestMethod ` -Headers $AzureManagementHeader ` -Method 'GET' ` - -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans?api-version=2024-04-03')).value | Where-Object {$_.name -eq $ScalingPlanName} + -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans?api-version=2023-09-05')).value | Where-Object {$_.name -eq $ScalingPlanName} # Disable autoscale for the host pool: https://learn.microsoft.com/rest/api/desktopvirtualization/scaling-plans/update if ($ScalingPlanExists) { Invoke-RestMethod ` - -Body (@{properties = @{hostPoolReferences = @(@{hostPoolArmPath = $HostPoolResourceId; scalingPlanEnabled = $false})}} | ConvertTo-Json) ` + -Body (@{properties = @{hostPoolReferences = @(@{hostPoolArmPath = $HostPoolResourceId; scalingPlanEnabled = $false})}} | ConvertTo-Json -Depth 3) ` -Headers $AzureManagementHeader ` -Method 'PATCH' ` - -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans/' + $ScalingPlanName + '?api-version=2024-04-03') | Out-Null + -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans/' + $ScalingPlanName + '?api-version=2023-09-05') | Out-Null } \ No newline at end of file diff --git a/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-AzureMarketplaceTerms.ps1 b/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-AzureMarketplaceTerms.ps1 index 0c3873cbd..dbdf82f11 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-AzureMarketplaceTerms.ps1 +++ b/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-AzureMarketplaceTerms.ps1 @@ -2,7 +2,9 @@ param ( [string]$ImageOffer, [string]$ImagePublisher, [string]$ImageSku, - [string]$ResourceManagerUri + [string]$ResourceManagerUri, + [string]$SubscriptionId, + [string]$UserAssignedIdentityClientId ) # Fix the resource manager URI since only AzureCloud contains a trailing slash diff --git a/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-HostPoolRegistrationToken.ps1 b/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-HostPoolRegistrationToken.ps1 deleted file mode 100644 index 87e183781..000000000 --- a/src/bicep/add-ons/azure-virtual-desktop/artifacts/Set-HostPoolRegistrationToken.ps1 +++ /dev/null @@ -1,57 +0,0 @@ -Param( - [string]$HostPoolName, - [string]$HostPoolResourceGroupName, - [string]$KeyVaultUri, - [string]$ResourceManagerUri, - [string]$SubscriptionId, - [string]$UserAssignedIdentityClientId -) - -$ErrorActionPreference = 'Stop' -$WarningPreference = 'SilentlyContinue' - -# Fix the resource manager URI since only AzureCloud contains a trailing slash -$ResourceManagerUriFixed = if($ResourceManagerUri[-1] -eq '/'){$ResourceManagerUri} else {$ResourceManagerUri + '/'} - -# Get an access token for Azure resources -$AzureManagementAccessToken = (Invoke-RestMethod ` - -Headers @{Metadata="true"} ` - -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token - -# Set header for Azure Management API -$AzureManagementHeader = @{ - 'Content-Type'='application/json' - 'Authorization'='Bearer ' + $AzureManagementAccessToken -} - -# Use the access token to update the host pool registration token -Invoke-RestMethod ` - -Body (@{properties = @{registrationInfo = @{expirationTime = $(Get-Date).AddMinutes(90); registrationTokenOperation = "Update" }}} | ConvertTo-Json) ` - -Headers $AzureManagementHeader ` - -Method 'PATCH' ` - -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $HostPoolResourceGroupName + '/providers/Microsoft.DesktopVirtualization/hostPools/' + $HostPoolName + '?api-version=2022-02-10-preview') | Out-Null - -# Use the access token to get the host pool registration token -$HostPoolRegistrationToken = (Invoke-RestMethod ` - -Headers $AzureManagementHeader ` - -Method 'POST' ` - -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $HostPoolResourceGroupName + '/providers/Microsoft.DesktopVirtualization/hostPools/' + $HostPoolName + '/retrieveRegistrationToken?api-version=2022-02-10-preview')).token - -# Get an access token for the Azure key vault -$KeyVaultAccessToken = (Invoke-RestMethod ` - -Headers @{Metadata="true"} ` - -Method 'GET' ` - -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $KeyVaultUri + '&client_id=' + $UserAssignedIdentityClientId)).access_token - -# Set header for Azure Key Vault API -$KeyVaultHeader = @{ - 'Content-Type'='application/json' - 'Authorization'='Bearer ' + $KeyVaultAccessToken -} - -# Create a key vault secret with the host pool registration token -Invoke-RestMethod ` - -Body (@{value = $HostPoolRegistrationToken} | ConvertTo-Json) ` - -Headers $KeyVaultHeader ` - -Method 'PUT' ` - -Uri $($KeyVaultUri + '/secrets/avdHostPoolRegistrationToken?api-version=7.4') | Out-Null \ No newline at end of file diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/common/function.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/common/function.bicep deleted file mode 100644 index 347a13908..000000000 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/common/function.bicep +++ /dev/null @@ -1,27 +0,0 @@ -param files object -param functionAppName string -param functionName string -param schedule string - -resource functionApp 'Microsoft.Web/sites@2020-12-01' existing = { - name: functionAppName -} - -resource function 'Microsoft.Web/sites/functions@2020-12-01' = { - parent: functionApp - name: functionName - properties: { - config: { - disabled: false - bindings: [ - { - name: 'Timer' - type: 'timerTrigger' - direction: 'in' - schedule: schedule - } - ] - } - files: files - } -} diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/controlPlane.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/controlPlane.bicep deleted file mode 100644 index 441ac9f53..000000000 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/controlPlane.bicep +++ /dev/null @@ -1,103 +0,0 @@ -targetScope = 'subscription' - -param activeDirectorySolution string -param avdPrivateDnsZoneResourceId string -param customImageId string -param customRdpProperty string -param deploymentNameSuffix string -param deploymentUserAssignedIdentityClientId string -param deploymentUserAssignedIdentityPrincipalId string -param desktopFriendlyName string -param diskSku string -param domainName string -param enableAvdInsights bool -param hostPoolPublicNetworkAccess string -param hostPoolType string -param imageOffer string -param imagePublisher string -param imageSku string -param imageVersionResourceId string -param locationControlPlane string -param locationVirtualMachines string -param logAnalyticsWorkspaceResourceId string -param managementVirtualMachineName string -param maxSessionLimit int -param mlzTags object -param namingConvention object -param resourceGroupControlPlane string -param resourceGroupManagement string -param roleDefinitions object -param securityPrincipalObjectIds array -param serviceToken string -param sessionHostNamePrefix string -param subnetResourceId string -param tags object -param validationEnvironment bool -param virtualMachineSize string - -var galleryImageOffer = empty(imageVersionResourceId) ? '"${imageOffer}"' : 'null' -var galleryImagePublisher = empty(imageVersionResourceId) ? '"${imagePublisher}"' : 'null' -var galleryImageSku = empty(imageVersionResourceId) ? '"${imageSku}"' : 'null' -var galleryItemId = empty(imageVersionResourceId) ? '"${imagePublisher}.${imageOffer}${imageSku}"' : 'null' -var hostPoolName = namingConvention.hostPool -var imageType = empty(imageVersionResourceId) ? '"Gallery"' : '"CustomImage"' - -module hostPool 'hostPool.bicep' = { - name: 'deploy-vdpool-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupControlPlane) - params: { - activeDirectorySolution: activeDirectorySolution - avdPrivateDnsZoneResourceId: avdPrivateDnsZoneResourceId - customImageId: customImageId - customRdpProperty: customRdpProperty - deploymentUserAssignedIdentityPrincipalId: deploymentUserAssignedIdentityPrincipalId - diskSku: diskSku - domainName: domainName - enableAvdInsights: enableAvdInsights - galleryImageOffer: galleryImageOffer - galleryImagePublisher: galleryImagePublisher - galleryImageSku: galleryImageSku - galleryItemId: galleryItemId - hostPoolDiagnosticSettingName: namingConvention.hostPoolDiagnosticSetting - hostPoolName: hostPoolName - hostPoolNetworkInterfaceName: namingConvention.hostPoolNetworkInterface - hostPoolPrivateEndpointName: namingConvention.hostPoolPrivateEndpoint - hostPoolPublicNetworkAccess: hostPoolPublicNetworkAccess - hostPoolType: hostPoolType - imageType: imageType - location: locationControlPlane - logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId - maxSessionLimit: maxSessionLimit - mlzTags: mlzTags - sessionHostNamePrefix: sessionHostNamePrefix - subnetResourceId: subnetResourceId - tags: tags - validationEnvironment: validationEnvironment - virtualMachineSize: virtualMachineSize - } -} - -module applicationGroup 'applicationGroup.bicep' = { - name: 'deploy-vdag-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupControlPlane) - params: { - deploymentNameSuffix: deploymentNameSuffix - deploymentUserAssignedIdentityClientId: deploymentUserAssignedIdentityClientId - deploymentUserAssignedIdentityPrincipalId: deploymentUserAssignedIdentityPrincipalId - desktopApplicationGroupName: replace(namingConvention.applicationGroup, serviceToken, 'desktop') - hostPoolResourceId: hostPool.outputs.resourceId - locationControlPlane: locationControlPlane - locationVirtualMachines: locationVirtualMachines - mlzTags: mlzTags - resourceGroupManagement: resourceGroupManagement - roleDefinitions: roleDefinitions - securityPrincipalObjectIds: securityPrincipalObjectIds - desktopFriendlyName: desktopFriendlyName - tags: tags - virtualMachineName: managementVirtualMachineName - } -} - -output applicationGroupResourceId string = applicationGroup.outputs.resourceId -output hostPoolName string = hostPool.outputs.name -output hostPoolResourceId string = hostPool.outputs.resourceId diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/azureFiles/azureFiles.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/azureFiles/azureFiles.bicep index 4d2cc6277..ff4f3f0b6 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/azureFiles/azureFiles.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/azureFiles/azureFiles.bicep @@ -12,9 +12,7 @@ param encryptionUserAssignedIdentityResourceId string param fileShares array param fslogixShareSizeInGB int param fslogixContainerType string -param fslogixStorageService string -param functionAppName string -param hostPoolName string +param hostPoolResourceId string param keyVaultUri string param location string param managementVirtualMachineName string @@ -23,9 +21,7 @@ param namingConvention object param netbios string param organizationalUnitPath string param recoveryServicesVaultName string -param resourceGroupControlPlane string param resourceGroupManagement string -param resourceGroupStorage string param securityPrincipalObjectIds array param securityPrincipalNames array param serviceToken string @@ -51,10 +47,10 @@ var smbSettings = { } var storageAccountNamePrefix = uniqueString(replace(namingConvention.storageAccount, serviceToken, 'file-fslogix'), resourceGroup().id) var storageRedundancy = availability == 'availabilityZones' ? '_ZRS' : '_LRS' -var tagsPrivateEndpoints = union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Network/privateEndpoints') ? tags['Microsoft.Network/privateEndpoints'] : {}, mlzTags) -var tagsStorageAccounts = union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Storage/storageAccounts') ? tags['Microsoft.Storage/storageAccounts'] : {}, mlzTags) -var tagsRecoveryServicesVault = union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.recoveryServices/vaults') ? tags['Microsoft.recoveryServices/vaults'] : {}, mlzTags) -var tagsVirtualMachines = union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Compute/virtualMachines') ? tags['Microsoft.Compute/virtualMachines'] : {}, mlzTags) +var tagsPrivateEndpoints = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) +var tagsStorageAccounts = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Storage/storageAccounts'] ?? {}, mlzTags) +var tagsRecoveryServicesVault = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.recoveryServices/vaults'] ?? {}, mlzTags) +var tagsVirtualMachines = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/virtualMachines'] ?? {}, mlzTags) resource storageAccounts 'Microsoft.Storage/storageAccounts@2022-09-01' = [for i in range(0, storageCount): { name: take('${storageAccountNamePrefix}${padLeft(i + storageIndex, 2, '0')}', 15) @@ -206,6 +202,7 @@ resource privateDnsZoneGroups 'Microsoft.Network/privateEndpoints/privateDnsZone ] }] +// Sets NTFS permissions on the file shares module ntfsPermissions '../runCommand.bicep' = { name: 'set-ntfs-permissions-${deploymentNameSuffix}' scope: resourceGroup(resourceGroupManagement) @@ -245,7 +242,7 @@ module ntfsPermissions '../runCommand.bicep' = { } { name: 'StorageAccountResourceGroupName' - value: resourceGroupStorage + value: resourceGroup().name } { name: 'StorageCount' @@ -283,6 +280,7 @@ module ntfsPermissions '../runCommand.bicep' = { ] } +// Deploys backup items for Azure Files module recoveryServices 'recoveryServices.bicep' = if (enableRecoveryServices) { name: 'deploy-backup-${deploymentNameSuffix}' scope: resourceGroup(resourceGroupManagement) @@ -291,7 +289,7 @@ module recoveryServices 'recoveryServices.bicep' = if (enableRecoveryServices) { fileShares: fileShares location: location recoveryServicesVaultName: recoveryServicesVaultName - resourceGroupStorage: resourceGroupStorage + resourceGroupStorage: resourceGroup().name storageAccountNamePrefix: storageAccountNamePrefix storageCount: storageCount storageIndex: storageIndex @@ -302,22 +300,4 @@ module recoveryServices 'recoveryServices.bicep' = if (enableRecoveryServices) { ] } -module autoIncreaseStandardFileShareQuota '../../common/function.bicep' = if (fslogixStorageService == 'AzureFiles Premium' && storageCount > 0) { - name: 'deploy-file-share-scaling-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupManagement) - params: { - files: { - 'requirements.psd1': loadTextContent('../../../artifacts/auto-increase-file-share/requirements.psd1') - 'run.ps1': loadTextContent('../../../artifacts/auto-increase-file-share/run.ps1') - '../profile.ps1': loadTextContent('../../../artifacts/auto-increase-file-share/profile.ps1') - } - functionAppName: functionAppName - functionName: 'auto-increase-file-share-quota' - schedule: '0 */15 * * * *' - } - dependsOn: [ - recoveryServices - ] -} - output storageAccountNamePrefix string = storageAccountNamePrefix diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/fslogix.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/fslogix.bicep index d4555ce84..3a7fb800d 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/fslogix.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/fslogix/fslogix.bicep @@ -1,12 +1,12 @@ targetScope = 'subscription' -param existingSharedActiveDirectoryConnection bool param activeDirectorySolution string param availability string param azureFilesPrivateDnsZoneResourceId string param subnets array param deploymentNameSuffix string param deploymentUserAssignedIdentityClientId string +param deploymentUserAssignedIdentityPrincipalId string param dnsServers string @secure() param domainJoinPassword string @@ -14,11 +14,13 @@ param domainJoinPassword string param domainJoinUserPrincipalName string param domainName string param encryptionUserAssignedIdentityResourceId string +param existingSharedActiveDirectoryConnection bool param fileShares array -param fslogixShareSizeInGB int param fslogixContainerType string +param fslogixShareSizeInGB int param fslogixStorageService string -param functionAppName string +param functionAppPrincipalId string +param hostPoolResourceId string param keyVaultUri string param location string param managementVirtualMachineName string @@ -27,9 +29,8 @@ param namingConvention object param netbios string param organizationalUnitPath string param recoveryServices bool -param resourceGroupControlPlane string param resourceGroupManagement string -param resourceGroupStorage string +param resourceGroupName string param securityPrincipalObjectIds array param securityPrincipalNames array param serviceToken string @@ -42,15 +43,43 @@ param storageService string param subnetResourceId string param tags object -var hostPoolName = namingConvention.hostPool +var tagsNetAppAccount = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.NetApp/netAppAccounts'] ?? {}, mlzTags) +var tagsVirtualMachines = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/virtualMachines'] ?? {}, mlzTags) -var tagsNetAppAccount = union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.NetApp/netAppAccounts') ? tags['Microsoft.NetApp/netAppAccounts'] : {}, mlzTags) -var tagsVirtualMachines = union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Compute/virtualMachines') ? tags['Microsoft.Compute/virtualMachines'] : {}, mlzTags) +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { + name: resourceGroupName + location: location + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Resources/resourceGroups'] ?? {}, mlzTags) +} + +// Role Assignment for FSLogix +// Purpose: assigns the Storage Account Contributor role to the managed identity on the +// management virtual machine storage resource group to domain join storage account(s) & set NTFS permissions on the file share(s) +module roleAssignment_Storage '../common/roleAssignments/resourceGroup.bicep' = { + name: 'assign-role-storage-${deploymentNameSuffix}' + scope: resourceGroup + params: { + principalId: deploymentUserAssignedIdentityPrincipalId + principalType: 'ServicePrincipal' + roleDefinitionId: '17d1049b-9a84-46fb-8f53-869881c3d3ab' + } +} + +// Required role assignment for the funciton to manage the quota on Azure Files Premium +module roleAssignments_resourceGroup '../common/roleAssignments/resourceGroup.bicep' = if (fslogixStorageService == 'AzureFiles Premium') { + name: 'set-role-assignment-${deploymentNameSuffix}' + scope: resourceGroup + params: { + principalId: functionAppPrincipalId + principalType: 'ServicePrincipal' + roleDefinitionId: '17d1049b-9a84-46fb-8f53-869881c3d3ab' // Storage Account Contributor + } +} // Azure NetApp Files for Fslogix module azureNetAppFiles 'azureNetAppFiles.bicep' = if (storageService == 'AzureNetAppFiles') { name: 'deploy-anf-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupStorage) + scope: resourceGroup params: { existingSharedActiveDirectoryConnection: existingSharedActiveDirectoryConnection delegatedSubnetResourceId: filter(subnets, subnet => contains(subnet.name, 'AzureNetAppFiles'))[0].id @@ -79,7 +108,7 @@ module azureNetAppFiles 'azureNetAppFiles.bicep' = if (storageService == 'AzureN // Azure Files for FSLogix module azureFiles 'azureFiles/azureFiles.bicep' = if (storageService == 'AzureFiles') { name: 'deploy-azure-files-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupStorage) + scope: resourceGroup params: { activeDirectorySolution: activeDirectorySolution availability: availability @@ -93,8 +122,7 @@ module azureFiles 'azureFiles/azureFiles.bicep' = if (storageService == 'AzureFi fileShares: fileShares fslogixContainerType: fslogixContainerType fslogixShareSizeInGB: fslogixShareSizeInGB - fslogixStorageService: fslogixStorageService - functionAppName: functionAppName + hostPoolResourceId: hostPoolResourceId keyVaultUri: keyVaultUri location: location managementVirtualMachineName: managementVirtualMachineName @@ -103,7 +131,6 @@ module azureFiles 'azureFiles/azureFiles.bicep' = if (storageService == 'AzureFi organizationalUnitPath: organizationalUnitPath recoveryServicesVaultName: namingConvention.recoveryServicesVault resourceGroupManagement: resourceGroupManagement - resourceGroupStorage: resourceGroupStorage securityPrincipalNames: securityPrincipalNames securityPrincipalObjectIds: securityPrincipalObjectIds serviceToken: serviceToken @@ -114,9 +141,7 @@ module azureFiles 'azureFiles/azureFiles.bicep' = if (storageService == 'AzureFi storageSku: storageSku subnetResourceId: subnetResourceId tags: tags - hostPoolName: hostPoolName mlzTags: mlzTags - resourceGroupControlPlane: resourceGroupControlPlane } } diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/logic.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/logic.bicep deleted file mode 100644 index 1ef2d017e..000000000 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/logic.bicep +++ /dev/null @@ -1,100 +0,0 @@ -targetScope = 'subscription' - -param activeDirectorySolution string -param deploymentLocations array -param diskSku string -param domainName string -param fileShareNames object -param fslogixContainerType string -param fslogixStorageService string -param imageOffer string -param imagePublisher string -param imageSku string -param imageVersionResourceId string -param locations object -param locationVirtualMachines string -param networkName string -param resourceGroupControlPlane string -param resourceGroupFeedWorkspace string -param resourceGroupHosts string -param resourceGroupManagement string -param resourceGroupsNetwork array -param resourceGroupStorage string -param securityPrincipals array -param serviceName string -param sessionHostCount int -param sessionHostIndex int -param virtualMachineNamePrefix string -param virtualMachineSize string - -// BATCH SESSION HOSTS -// The following variables are used to determine the batches to deploy any number of AVD session hosts. -var maxResourcesPerTemplateDeployment = 88 // This is the max number of session hosts that can be deployed from the sessionHosts.bicep file in each batch / for loop. Math: (800 - ) / -var divisionValue = sessionHostCount / maxResourcesPerTemplateDeployment // This determines if any full batches are required. -var divisionRemainderValue = sessionHostCount % maxResourcesPerTemplateDeployment // This determines if any partial batches are required. -var sessionHostBatchCount = divisionRemainderValue > 0 ? divisionValue + 1 : divisionValue // This determines the total number of batches needed, whether full and / or partial. - -// BATCH AVAILABILITY SETS -// The following variables are used to determine the number of availability sets. -var maxAvSetMembers = 200 // This is the max number of session hosts that can be deployed in an availability set. -var beginAvSetRange = sessionHostIndex / maxAvSetMembers // This determines the availability set to start with. -var endAvSetRange = (sessionHostCount + sessionHostIndex) / maxAvSetMembers // This determines the availability set to end with. -var availabilitySetsCount = length(range(beginAvSetRange, (endAvSetRange - beginAvSetRange) + 1)) - -// OTHER LOGIC & COMPUTED VALUES -var customImageId = empty(imageVersionResourceId) ? 'null' : '"${imageVersionResourceId}"' -var fileShares = fileShareNames[fslogixContainerType] -var fslogix = fslogixStorageService == 'None' || !contains(activeDirectorySolution, 'DomainServices') ? false : true -var galleryImageOffer = empty(imageVersionResourceId) ? '"${imageOffer}"' : 'null' -var galleryImagePublisher = empty(imageVersionResourceId) ? '"${imagePublisher}"' : 'null' -var galleryImageSku = empty(imageVersionResourceId) ? '"${imageSku}"' : 'null' -var galleryItemId = empty(imageVersionResourceId) ? '"${imagePublisher}.${imageOffer}${imageSku}"' : 'null' -var imageType = empty(imageVersionResourceId) ? '"Gallery"' : '"CustomImage"' -var netbios = split(domainName, '.')[0] -var resourceGroups = union(resourceGroupsCommon, resourceGroupsNetworking, resourceGroupsStorage) -var resourceGroupsCommon = [ - resourceGroupControlPlane - resourceGroupFeedWorkspace - resourceGroupHosts - resourceGroupManagement -] -var resourceGroupsNetworking = length(deploymentLocations) == 2 ? resourceGroupsNetwork : [ - resourceGroupsNetwork[0] -] -var resourceGroupsStorage = fslogix ? [ - resourceGroupStorage -] : [] -var roleDefinitions = { - DesktopVirtualizationPowerOnContributor: '489581de-a3bd-480d-9518-53dea7416b33' - DesktopVirtualizationUser: '1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' - VirtualMachineUserLogin: 'fb879df8-f326-4884-b1cf-06f3ad86be52' -} -var securityPrincipalsCount = length(securityPrincipals) -var sessionHostNamePrefix = replace(virtualMachineNamePrefix, '${serviceName}${networkName}', '') -var smbServerLocation = locations[locationVirtualMachines].abbreviation -var storageSku = fslogixStorageService == 'None' ? 'None' : split(fslogixStorageService, ' ')[1] -var storageService = split(fslogixStorageService, ' ')[0] -var storageSuffix = environment().suffixes.storage -var timeDifference = locations[locationVirtualMachines].timeDifference -var timeZone = locations[locationVirtualMachines].timeZone -var vmTemplate = '{"domain":"${domainName}","galleryImageOffer":${galleryImageOffer},"galleryImagePublisher":${galleryImagePublisher},"galleryImageSKU":${galleryImageSku},"imageType":${imageType},"customImageId":${customImageId},"namePrefix":"${sessionHostNamePrefix}","osDiskType":"${diskSku}","vmSize":{"id":"${virtualMachineSize}","cores":null,"ram":null,"rdmaEnabled": false,"supportsMemoryPreservingMaintenance": true},"galleryItemId":${galleryItemId},"hibernate":false,"diskSizeGB":0,"securityType":"TrustedLaunch","secureBoot":true,"vTPM":true,"vmInfrastructureType":"Cloud","virtualProcessorCount":null,"memoryGB":null,"maximumMemoryGB":null,"minimumMemoryGB":null,"dynamicMemoryConfig":false}' - -output availabilitySetsCount int = availabilitySetsCount -output beginAvSetRange int = beginAvSetRange -output divisionRemainderValue int = divisionRemainderValue -output fileShares array = fileShares -output fslogix bool = fslogix -output maxResourcesPerTemplateDeployment int = maxResourcesPerTemplateDeployment -output netbios string = netbios -output resourceGroups array = resourceGroups -output roleDefinitions object = roleDefinitions -output sessionHostBatchCount int = sessionHostBatchCount -output securityPrincipalsCount int = securityPrincipalsCount -output smbServerLocation string = smbServerLocation -output storageSku string = storageSku -output storageService string = storageService -output storageSuffix string = storageSuffix -output timeDifference string = timeDifference -output timeZone string = timeZone -output vmTemplate string = vmTemplate diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/applicationGroup.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/applicationGroup.bicep similarity index 51% rename from src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/applicationGroup.bicep rename to src/bicep/add-ons/azure-virtual-desktop/modules/management/applicationGroup.bicep index 9093c1d72..149f3e530 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/applicationGroup.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/applicationGroup.bicep @@ -1,43 +1,28 @@ param deploymentNameSuffix string param deploymentUserAssignedIdentityClientId string -param deploymentUserAssignedIdentityPrincipalId string param desktopApplicationGroupName string param desktopFriendlyName string param hostPoolResourceId string param locationControlPlane string param locationVirtualMachines string param mlzTags object -param resourceGroupManagement string -param roleDefinitions object param securityPrincipalObjectIds array param tags object param virtualMachineName string -resource applicationGroup 'Microsoft.DesktopVirtualization/applicationGroups@2024-04-03' = { +resource applicationGroup 'Microsoft.DesktopVirtualization/applicationGroups@2023-09-05' = { name: desktopApplicationGroupName location: locationControlPlane - tags: union({ - 'cm-resource-parent': hostPoolResourceId - }, contains(tags, 'Microsoft.DesktopVirtualization/applicationGroups') ? tags['Microsoft.DesktopVirtualization/applicationGroups'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.DesktopVirtualization/applicationGroups'] ?? {}, mlzTags) properties: { hostPoolArmPath: hostPoolResourceId applicationGroupType: 'Desktop' } } -resource roleAssignment_ManagedIdentity 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(deploymentUserAssignedIdentityPrincipalId, '86240b0e-9422-4c43-887b-b61143f32ba8', applicationGroup.id) - scope: applicationGroup - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '86240b0e-9422-4c43-887b-b61143f32ba8') // Desktop Virtualization Application Group Contributor (Purpose: updates the friendly name for the desktop) - principalId: deploymentUserAssignedIdentityPrincipalId - principalType: 'ServicePrincipal' - } -} - -// Adds a friendly name to the SessionDesktop application for the desktop application group +// Run Command to update the Application +// Purpose: executes a script to update the friendly name on the application module applicationFriendlyName '../common/runCommand.bicep' = if (!empty(desktopFriendlyName)) { - scope: resourceGroup(resourceGroupManagement) name: 'deploy-vdapp-friendly-name-${deploymentNameSuffix}' params: { location: locationVirtualMachines @@ -69,25 +54,18 @@ module applicationFriendlyName '../common/runCommand.bicep' = if (!empty(desktop } ] script: loadTextContent('../../artifacts/Update-AvdDesktop.ps1') - tags: union( - { - 'cm-resource-parent': hostPoolResourceId - }, - contains(tags, 'Microsoft.Compute/virtualMachines') ? tags['Microsoft.Compute/virtualMachines'] : {}, - mlzTags - ) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/virtualMachines'] ?? {}, mlzTags) virtualMachineName: virtualMachineName } - dependsOn: [ - roleAssignment_ManagedIdentity - ] } -resource roleAssignment_Users 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for i in range(0, length(securityPrincipalObjectIds)): { +// Role Assignment for AVD access +// Purpose: assigns the Desktop Virtualization User role to the application group for the specified security principals +resource roleAssignment_ApplicationGroup 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for i in range(0, length(securityPrincipalObjectIds)): { + name: guid(securityPrincipalObjectIds[i], '1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63', applicationGroup.id) scope: applicationGroup - name: guid(securityPrincipalObjectIds[i], roleDefinitions.DesktopVirtualizationUser, desktopApplicationGroupName) properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitions.DesktopVirtualizationUser) + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63') principalId: securityPrincipalObjectIds[i] } }] diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/diskAccess.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/diskAccess.bicep index db57de786..4eb8fc219 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/diskAccess.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/diskAccess.bicep @@ -1,26 +1,21 @@ -param hostPoolName string +param hostPoolResourceId string param location string param mlzTags object param namingConvention object -param resourceGroupControlPlane string param subnetResourceId string param tags object resource diskAccess 'Microsoft.Compute/diskAccesses@2021-04-01' = { name: namingConvention.diskAccess location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Compute/diskAccesses') ? tags['Microsoft.Compute/diskAccesses'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/diskAccesses'] ?? {}, mlzTags) properties: {} } resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { name: namingConvention.diskAccessPrivateEndpoint location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Network/privateEndpoints') ? tags['Microsoft.Network/privateEndpoints'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) properties: { customNetworkInterfaceName: namingConvention.diskAccessNetworkInterface privateLinkServiceConnections: [ @@ -40,5 +35,4 @@ resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { } } - output resourceId string = diskAccess.id diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/functionApp.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/functionApp.bicep index f4af029e1..9d4ccc520 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/functionApp.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/functionApp.bicep @@ -2,21 +2,20 @@ param delegatedSubnetResourceId string param deploymentNameSuffix string param enableApplicationInsights bool param environmentAbbreviation string -param hostPoolName string +param hostPoolResourceId string param keyExpirationInDays int = 30 param location string = resourceGroup().location param logAnalyticsWorkspaceResourceId string +param mlzTags object param namingConvention object param privateDnsZoneResourceIdPrefix string param privateDnsZones array param privateLinkScopeResourceId string param resourceAbbreviations object -param resourceGroupControlPlane string -param resourceGroupStorage string +param resourceGroupProfiles string param serviceToken string param subnetResourceId string param tags object -param timeDifference string var cloudSuffix = replace(replace(environment().resourceManager, 'https://management.', ''), '/', '') var functionAppKeyword = environment().name == 'AzureCloud' || environment().name == 'AzureUSGovernment' ? 'azurewebsites' : 'appservice' @@ -52,13 +51,13 @@ var storageSubResources = [ resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { name: replace(namingConvention.userAssignedIdentity, serviceToken, service) location: location - tags: tags[?'Microsoft.ManagedIdentity/userAssignedIdentities'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.ManagedIdentity/userAssignedIdentities'] ?? {}, mlzTags) } resource vault 'Microsoft.KeyVault/vaults@2022-07-01' = { name: '${resourceAbbreviations.keyVaults}${uniqueString(replace(namingConvention.keyVault, serviceToken, service), resourceGroup().id)}' location: location - tags: tags[?'Microsoft.KeyVault/vaults'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.KeyVault/vaults'] ?? {}, mlzTags) properties: { enabledForDeployment: false enabledForDiskEncryption: false @@ -95,7 +94,7 @@ resource roleAssignment_Encryption 'Microsoft.Authorization/roleAssignments@2020 resource privateEndpoint_vault 'Microsoft.Network/privateEndpoints@2023-04-01' = { name: replace(namingConvention.keyVaultPrivateEndpoint, serviceToken, service) location: location - tags: tags[?'Microsoft.Network/privateEndpoints'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) properties: { customNetworkInterfaceName: replace(namingConvention.keyVaultNetworkInterface, serviceToken, service) privateLinkServiceConnections: [ @@ -169,7 +168,7 @@ resource key_storageAccount 'Microsoft.KeyVault/vaults/keys@2022-07-01' = { resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { name: uniqueString(replace(namingConvention.storageAccount, serviceToken, service), resourceGroup().id) location: location - tags: tags[?'Microsoft.Storage/storageAccounts'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Storage/storageAccounts'] ?? {}, mlzTags) sku: { name: 'Standard_LRS' } @@ -247,7 +246,7 @@ resource privateEndpoints_storage 'Microsoft.Network/privateEndpoints@2023-04-01 for resource in storageSubResources: { name: replace(resource.pe, serviceToken, service) location: location - tags: tags[?'Microsoft.Network/privateEndpoints'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) properties: { customNetworkInterfaceName: replace(resource.nic, serviceToken, service) privateLinkServiceConnections: [ @@ -313,7 +312,7 @@ resource diagnosticSetting_storage_blob 'Microsoft.Insights/diagnosticsettings@2 resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = if (enableApplicationInsights) { name: replace(namingConvention.applicationInsights, serviceToken, service) location: location - tags: tags[?'Microsoft.Insights/components'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Insights/components'] ?? {}, mlzTags) properties: { Application_Type: 'web' publicNetworkAccessForIngestion: 'Disabled' @@ -334,11 +333,11 @@ module privateLinkScope 'privateLinkScope.bicep' = if (enableApplicationInsights resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = { name: replace(namingConvention.appServicePlan, serviceToken, service) location: location - tags: tags[?'Microsoft.Web/serverfarms'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Web/serverfarms'] ?? {}, mlzTags) sku: { - name: 'P0v3' + name: 'P1v3' tier: 'PremiumV3' - size: 'P0v3' + size: 'P1v3' family: 'Pv3' capacity: 1 } @@ -348,7 +347,7 @@ resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = { resource functionApp 'Microsoft.Web/sites@2023-01-01' = { name: uniqueString(replace(namingConvention.functionApp, serviceToken, service), resourceGroup().id) location: location - tags: tags[?'Microsoft.Web/sites'] ?? {} + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Web/sites'] ?? {}, mlzTags) kind: 'functionapp' identity: { type: 'SystemAssigned' @@ -389,37 +388,13 @@ resource functionApp 'Microsoft.Web/sites@2023-01-01' = { name: 'WEBSITE_LOAD_USER_PROFILE' value: '1' } - { - name: 'EnvironmentName' - value: environment().name - } { name: 'FileShareName' value: 'profile-containers' } - { - name: 'HostPoolName' - value: hostPoolName - } - { - name: 'HostPoolResourceGroupName' - value: resourceGroupControlPlane - } - { - name: 'LogOffMessageBody' - value: 'This session is about to be logged off. Please save your work.' - } - { - name: 'LogOffMessageTitle' - value: 'Session Log Off' - } - { - name: 'MaintenanceTagName' - value: 'Maintenance' - } { name: 'ResourceGroupName' - value: resourceGroupStorage + value: resourceGroupProfiles } { name: 'ResourceManagerUrl' @@ -436,14 +411,6 @@ resource functionApp 'Microsoft.Web/sites@2023-01-01' = { name: 'SubscriptionId' value: subscription().subscriptionId } - { - name: 'TenantId' - value: subscription().tenantId - } - { - name: 'TimeDifference' - value: timeDifference - } ], enableApplicationInsights ? [ { name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' @@ -460,7 +427,7 @@ resource functionApp 'Microsoft.Web/sites@2023-01-01' = { } ftpsState: 'Disabled' netFrameworkVersion: 'v6.0' - powerShellVersion: '7.2' + powerShellVersion: '7.4' publicNetworkAccess: 'Disabled' use32BitWorkerProcess: false } @@ -473,6 +440,7 @@ resource functionApp 'Microsoft.Web/sites@2023-01-01' = { resource privateEndpoint_functionApp 'Microsoft.Network/privateEndpoints@2023-04-01' = { name: replace(namingConvention.functionAppPrivateEndpoint, serviceToken, service) location: location + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) properties: { customNetworkInterfaceName: replace(namingConvention.functionAppNetworkInterface, serviceToken, service) privateLinkServiceConnections: [ @@ -508,17 +476,6 @@ resource privateDnsZoneGroup_functionApp 'Microsoft.Network/privateEndpoints/pri } } -// Required role assignment for the funciton to manage the quota on Azure Files Premium -module roleAssignments_resourceGroups '../common/roleAssignments/resourceGroup.bicep' = { - name: 'set-role-assignment-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupStorage) - params: { - principalId: functionApp.identity.principalId - principalType: 'ServicePrincipal' - roleDefinitionId: '17d1049b-9a84-46fb-8f53-869881c3d3ab' // Storage Account Contributor - } -} - // Required role assignment to support the zero trust deployment of a function app module roleAssignment_storageAccount '../common/roleAssignments/storageAccount.bicep' = { name: 'set-role-assignment-storage-${deploymentNameSuffix}' @@ -541,4 +498,28 @@ module scmARecord 'aRecord.bicep' = { } } +resource function 'Microsoft.Web/sites/functions@2020-12-01' = { + parent: functionApp + name: 'auto-increase-file-share-quota' + properties: { + config: { + disabled: false + bindings: [ + { + name: 'Timer' + type: 'timerTrigger' + direction: 'in' + schedule: '0 */15 * * * *' + } + ] + } + files: { + 'requirements.psd1': loadTextContent('../../artifacts/auto-increase-file-share/requirements.psd1') + 'run.ps1': loadTextContent('../../artifacts/auto-increase-file-share/run.ps1') + '../profile.ps1': loadTextContent('../../artifacts/auto-increase-file-share/profile.ps1') + } + } +} + output functionAppName string = functionApp.name +output functionAppPrincipalId string = functionApp.identity.principalId diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/hostPool.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/hostPool.bicep similarity index 75% rename from src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/hostPool.bicep rename to src/bicep/add-ons/azure-virtual-desktop/modules/management/hostPool.bicep index e98bf306c..40ba676bc 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/controlPlane/hostPool.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/hostPool.bicep @@ -1,6 +1,5 @@ param activeDirectorySolution string param avdPrivateDnsZoneResourceId string -param deploymentUserAssignedIdentityPrincipalId string param customImageId string param customRdpProperty string param diskSku string @@ -33,9 +32,7 @@ var customRdpProperty_Complete = contains(activeDirectorySolution, 'MicrosoftEnt resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' = { name: hostPoolName location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroup().name}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.DesktopVirtualization/hostPools') ? tags['Microsoft.DesktopVirtualization/hostPools'] : {}, mlzTags) + tags: union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroup().name}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, tags[?'Microsoft.DesktopVirtualization/hostPools'] ?? {}, mlzTags) properties: { customRdpProperty: customRdpProperty_Complete hostPoolType: hostPoolType @@ -57,9 +54,7 @@ resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' = { resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { name: hostPoolPrivateEndpointName location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroup().name}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Network/privateEndpoints') ? tags['Microsoft.Network/privateEndpoints'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPool.id}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) properties: { customNetworkInterfaceName: hostPoolNetworkInterfaceName privateLinkServiceConnections: [ @@ -94,16 +89,6 @@ resource privateDnsZoneGroup 'Microsoft.Network/privateEndpoints/privateDnsZoneG } } -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(deploymentUserAssignedIdentityPrincipalId, '2ad6aaab-ead9-4eaa-8ac5-da422f562408', hostPool.id) - scope: hostPool - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '2ad6aaab-ead9-4eaa-8ac5-da422f562408') // Desktop Virtualization Session Host Operator (Purpose: sets drain mode on the AVD session hosts) - principalId: deploymentUserAssignedIdentityPrincipalId - principalType: 'ServicePrincipal' - } -} - resource diagnosticSetting 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (enableAvdInsights) { name: hostPoolDiagnosticSettingName scope: hostPool diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/management.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/management.bicep index 6102b23f9..874468670 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/management.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/management.bicep @@ -1,8 +1,13 @@ targetScope = 'subscription' +param activeDirectorySolution string param avdObjectId string +param avdPrivateDnsZoneResourceId string +param customImageId string +param customRdpProperty string param deployFslogix bool param deploymentNameSuffix string +param desktopFriendlyName string param diskEncryptionSetResourceId string param diskSku string @secure() @@ -13,9 +18,17 @@ param enableApplicationInsights bool param enableAvdInsights bool param environmentAbbreviation string param fslogixStorageService string +param hostPoolPublicNetworkAccess string +param hostPoolType string +param imageOffer string +param imagePublisher string +param imageSku string +param imageVersionResourceId string +param locationControlPlane string param locationVirtualMachines string param logAnalyticsWorkspaceRetention int param logAnalyticsWorkspaceSku string +param maxSessionLimit int param mlzTags object param namingConvention object param organizationalUnitPath string @@ -25,111 +38,152 @@ param privateLinkScopeResourceId string param recoveryServices bool param recoveryServicesGeo string param resourceAbbreviations object -param resourceGroupControlPlane string -param resourceGroupHosts string -param resourceGroupManagement string -param resourceGroupStorage string -param roleDefinitions object +param resourceGroupName string +param resourceGroupProfiles string +param securityPrincipalObjectIds array param serviceToken string +param sessionHostNamePrefix string param storageService string param subnetResourceId string param subnets array param tags object -param timeDifference string param timeZone string +param validationEnvironment bool @secure() param virtualMachinePassword string +param virtualMachineSize string param virtualMachineUsername string +var galleryImageOffer = empty(imageVersionResourceId) ? '"${imageOffer}"' : 'null' +var galleryImagePublisher = empty(imageVersionResourceId) ? '"${imagePublisher}"' : 'null' +var galleryImageSku = empty(imageVersionResourceId) ? '"${imageSku}"' : 'null' +var galleryItemId = empty(imageVersionResourceId) ? '"${imagePublisher}.${imageOffer}${imageSku}"' : 'null' var hostPoolName = namingConvention.hostPool -var resourceGroups = union( - [ - resourceGroupControlPlane - resourceGroupHosts - resourceGroupManagement - ], - deployFslogix ? [ - resourceGroupStorage - ] : [] -) +var imageType = empty(imageVersionResourceId) ? '"Gallery"' : '"CustomImage"' var userAssignedIdentityNamePrefix = namingConvention.userAssignedIdentity -var virtualNetworkName = split(subnetResourceId, '/')[8] -var virtualNetworkResourceGroupName = split(subnetResourceId, '/')[4] + +resource resourceGroup 'Microsoft.Resources/resourceGroups@2023-07-01' = { + name: resourceGroupName + location: locationControlPlane + tags: union({'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupName}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, tags[?'Microsoft.Resources/resourceGroups'] ?? {}, mlzTags) +} + +// Role Assignment for Autoscale +// Purpose: assigns the Desktop Virtualization Power On Off Contributor role to the +// Azure Virtual Desktop service to scale the host pool +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid(avdObjectId, '40c5ff49-9181-41f8-ae61-143b0e78555e', subscription().id) + properties: { + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e') + principalId: avdObjectId + } +} + +// Monitoring Resources for AVD Insights +// This module deploys a Log Analytics Workspace with a Data Collection Rule +module monitoring 'monitoring.bicep' = if (enableApplicationInsights || enableAvdInsights) { + name: 'deploy-monitoring-${deploymentNameSuffix}' + scope: resourceGroup + params: { + deploymentNameSuffix: deploymentNameSuffix + enableAvdInsights: enableAvdInsights + hostPoolResourceId: '${subscription().id}}/resourceGroups/${resourceGroup.name}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' + location: locationVirtualMachines + logAnalyticsWorkspaceRetention: logAnalyticsWorkspaceRetention + logAnalyticsWorkspaceSku: logAnalyticsWorkspaceSku + mlzTags: mlzTags + namingConvention: namingConvention + privateLinkScopeResourceId: privateLinkScopeResourceId + serviceToken: serviceToken + tags: tags + } +} + +module hostPool 'hostPool.bicep' = { + name: 'deploy-vdpool-${deploymentNameSuffix}' + scope: resourceGroup + params: { + activeDirectorySolution: activeDirectorySolution + avdPrivateDnsZoneResourceId: avdPrivateDnsZoneResourceId + customImageId: customImageId + customRdpProperty: customRdpProperty + diskSku: diskSku + domainName: domainName + enableAvdInsights: enableAvdInsights + galleryImageOffer: galleryImageOffer + galleryImagePublisher: galleryImagePublisher + galleryImageSku: galleryImageSku + galleryItemId: galleryItemId + hostPoolDiagnosticSettingName: namingConvention.hostPoolDiagnosticSetting + hostPoolName: hostPoolName + hostPoolNetworkInterfaceName: namingConvention.hostPoolNetworkInterface + hostPoolPrivateEndpointName: namingConvention.hostPoolPrivateEndpoint + hostPoolPublicNetworkAccess: hostPoolPublicNetworkAccess + hostPoolType: hostPoolType + imageType: imageType + location: locationControlPlane + logAnalyticsWorkspaceResourceId: monitoring.outputs.logAnalyticsWorkspaceResourceId + maxSessionLimit: maxSessionLimit + mlzTags: mlzTags + sessionHostNamePrefix: sessionHostNamePrefix + subnetResourceId: subnetResourceId + tags: tags + validationEnvironment: validationEnvironment + virtualMachineSize: virtualMachineSize + } +} module diskAccess 'diskAccess.bicep' = { - scope: resourceGroup(resourceGroupManagement) + scope: resourceGroup name: 'deploy-disk-access-${deploymentNameSuffix}' params: { - hostPoolName: hostPoolName + hostPoolResourceId: hostPool.outputs.resourceId location: locationVirtualMachines mlzTags: mlzTags namingConvention: namingConvention - resourceGroupControlPlane: resourceGroupControlPlane subnetResourceId: subnetResourceId tags: tags } } // Sets an Azure policy to disable public network access to managed disks -module policy 'policy.bicep' = { +module policy '../management/policy.bicep' = { name: 'deploy-policy-disks-${deploymentNameSuffix}' params: { diskAccessResourceId: diskAccess.outputs.resourceId - location: locationVirtualMachines - resourceGroupName: resourceGroupHosts + location: locationControlPlane + resourceGroupName: resourceGroup.name } } module deploymentUserAssignedIdentity 'userAssignedIdentity.bicep' = { - scope: resourceGroup(resourceGroupManagement) + scope: resourceGroup name: 'deploy-id-deployment-${deploymentNameSuffix}' params: { location: locationVirtualMachines name: replace(userAssignedIdentityNamePrefix, serviceToken, 'deployment') - tags: union( - { - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, - contains(tags, 'Microsoft.ManagedIdentity/userAssignedIdentities') - ? tags['Microsoft.ManagedIdentity/userAssignedIdentities'] - : {}, - mlzTags - ) + tags: union({'cm-resource-parent': hostPool.outputs.resourceId}, tags[?'Microsoft.ManagedIdentity/userAssignedIdentities'] ?? {}, mlzTags) } } - -// Role Assignments: Reader on the resource groups -//Purpose: domain join storage account(s) & set NTFS permissions on the file share(s) -module roleAssignments_deployment '../common/roleAssignments/resourceGroup.bicep' = [ - for i in range(0, length(resourceGroups)): { - scope: resourceGroup(resourceGroups[i]) - name: 'deploy-role-assignment-${i}-${deploymentNameSuffix}' - params: { - principalId: deploymentUserAssignedIdentity.outputs.principalId - principalType: 'ServicePrincipal' - roleDefinitionId: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' // Reader - } - } -] - -// Role Assignment: Storage Account Contributor on the storage resource group -// Purpose: domain join storage account(s) & set NTFS permissions on the file share(s) -module roleAssignment_StorageAccountContributor '../common/roleAssignments/resourceGroup.bicep' = { - scope: resourceGroup(resourceGroupStorage) - name: 'deploy-role-assignment-${deploymentNameSuffix}' +// Role Assignment for the AVD host pool +// Purpose: assigns the Desktop Virtualization Contributor role to the managed identity on the +// management virtual machine to set the drain mode on the AVD session hosts and manage the scaling plan +module roleAssignment_Management '../common/roleAssignments/resourceGroup.bicep' = { + name: 'assign-role-mgmt-${deploymentNameSuffix}' + scope: resourceGroup params: { principalId: deploymentUserAssignedIdentity.outputs.principalId principalType: 'ServicePrincipal' - roleDefinitionId: '17d1049b-9a84-46fb-8f53-869881c3d3ab' // Storage Account Contributor + roleDefinitionId: '082f0a83-3be5-4ba1-904c-961cca79b387' } } -// Management VM -// The management VM is required to execute PowerShell scripts. +// Management Virtual Machine +// Purpose: deploys the management VM is required to execute PowerShell scripts. module virtualMachine 'virtualMachine.bicep' = { name: 'deploy-mgmt-vm-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupManagement) + scope: resourceGroup params: { deploymentUserAssignedIdentityPrincipalId: deploymentUserAssignedIdentity.outputs.principalId deploymentUserAssignedIdentityResourceId: deploymentUserAssignedIdentity.outputs.resourceId @@ -139,106 +193,96 @@ module virtualMachine 'virtualMachine.bicep' = { domainJoinPassword: domainJoinPassword domainJoinUserPrincipalName: domainJoinUserPrincipalName domainName: domainName - hostPoolName: hostPoolName + hostPoolResourceId: hostPool.outputs.resourceId location: locationVirtualMachines mlzTags: mlzTags networkInterfaceName: replace(namingConvention.virtualMachineNetworkInterface, serviceToken, 'mgt') organizationalUnitPath: organizationalUnitPath - resourceGroupControlPlane: resourceGroupControlPlane - subnet: split(subnetResourceId, '/')[10] + subnetResourceId: subnetResourceId tags: tags virtualMachineName: replace(namingConvention.virtualMachine, serviceToken, 'mgt') virtualMachinePassword: virtualMachinePassword virtualMachineUsername: virtualMachineUsername - virtualNetwork: virtualNetworkName - virtualNetworkResourceGroup: virtualNetworkResourceGroupName } } -// Role Assignment required for Scaling Plan -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid(avdObjectId, roleDefinitions.DesktopVirtualizationPowerOnOffContributor, subscription().id) - properties: { - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions',roleDefinitions.DesktopVirtualizationPowerOnOffContributor) - principalId: avdObjectId +module applicationGroup 'applicationGroup.bicep' = { + name: 'deploy-vdag-${deploymentNameSuffix}' + scope: resourceGroup + params: { + deploymentNameSuffix: deploymentNameSuffix + deploymentUserAssignedIdentityClientId: deploymentUserAssignedIdentity.outputs.clientId + desktopApplicationGroupName: namingConvention.applicationGroup + hostPoolResourceId: hostPool.outputs.resourceId + locationControlPlane: locationControlPlane + locationVirtualMachines: locationVirtualMachines + mlzTags: mlzTags + securityPrincipalObjectIds: securityPrincipalObjectIds + desktopFriendlyName: desktopFriendlyName + tags: tags + virtualMachineName: virtualMachine.outputs.name } } -// Monitoring Resources for AVD Insights -// This module deploys a Log Analytics Workspace with a Data Collection Rule -module monitoring 'monitoring.bicep' = if (enableApplicationInsights || enableAvdInsights) { - name: 'deploy-monitoring-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupManagement) +module recoveryServicesVault 'recoveryServicesVault.bicep' = if (recoveryServices) { + name: 'deploy-rsv-${deploymentNameSuffix}' + scope: resourceGroup params: { - deploymentNameSuffix: deploymentNameSuffix - enableAvdInsights: enableAvdInsights - hostPoolName: hostPoolName + azureBlobsPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(privateDnsZones, name => contains(name, 'blob'))[0]}' + azureQueueStoragePrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(privateDnsZones, name => contains(name, 'queue'))[0]}' + deployFslogix: deployFslogix + hostPoolResourceId: hostPool.outputs.resourceId location: locationVirtualMachines - logAnalyticsWorkspaceRetention: logAnalyticsWorkspaceRetention - logAnalyticsWorkspaceSku: logAnalyticsWorkspaceSku mlzTags: mlzTags - namingConvention: namingConvention - privateLinkScopeResourceId: privateLinkScopeResourceId - resourceGroupControlPlane: resourceGroupControlPlane - serviceToken: serviceToken + recoveryServicesPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(privateDnsZones, name => startsWith(name, 'privatelink.${recoveryServicesGeo}.backup.windowsazure'))[0]}' + recoveryServicesVaultName: namingConvention.recoveryServicesVault + recoveryServicesVaultNetworkInterfaceName: namingConvention.recoveryServicesVaultNetworkInterface + recoveryServicesVaultPrivateEndpointName: namingConvention.recoveryServicesVaultPrivateEndpoint + storageService: storageService + subnetId: subnetResourceId tags: tags + timeZone: timeZone } } // Deploys the Auto Increase Premium File Share Quota solution on an Azure Function App -module functionApp 'functionApp.bicep' = if (deployFslogix && fslogixStorageService == 'AzureFiles Premium') { +module functionApp '../management/functionApp.bicep' = if (fslogixStorageService == 'AzureFiles Premium') { name: 'deploy-function-app-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupManagement) + scope: resourceGroup params: { delegatedSubnetResourceId: filter(subnets, subnet => contains(subnet.name, 'FunctionAppOutbound'))[0].id deploymentNameSuffix: deploymentNameSuffix enableApplicationInsights: enableApplicationInsights environmentAbbreviation: environmentAbbreviation - hostPoolName: hostPoolName + hostPoolResourceId: hostPool.outputs.resourceId logAnalyticsWorkspaceResourceId: monitoring.outputs.logAnalyticsWorkspaceResourceId + mlzTags: mlzTags namingConvention: namingConvention privateDnsZoneResourceIdPrefix: privateDnsZoneResourceIdPrefix privateDnsZones: privateDnsZones privateLinkScopeResourceId: privateLinkScopeResourceId resourceAbbreviations: resourceAbbreviations - resourceGroupControlPlane: resourceGroupControlPlane - resourceGroupStorage: resourceGroupStorage + resourceGroupProfiles: resourceGroupProfiles serviceToken: serviceToken subnetResourceId: subnetResourceId tags: tags - timeDifference: timeDifference - } -} - -module recoveryServicesVault 'recoveryServicesVault.bicep' = if (recoveryServices) { - name: 'deploy-rsv-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupManagement) - params: { - azureBlobsPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(privateDnsZones, name => contains(name, 'blob'))[0]}' - azureQueueStoragePrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(privateDnsZones, name => contains(name, 'queue'))[0]}' - deployFslogix: deployFslogix - hostPoolName: hostPoolName - location: locationVirtualMachines - mlzTags: mlzTags - recoveryServicesPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(privateDnsZones, name => startsWith(name, 'privatelink.${recoveryServicesGeo}.backup.windowsazure'))[0]}' - recoveryServicesVaultName: namingConvention.recoveryServicesVault - recoveryServicesVaultNetworkInterfaceName: namingConvention.recoveryServicesVaultNetworkInterface - recoveryServicesVaultPrivateEndpointName: namingConvention.recoveryServicesVaultPrivateEndpoint - resourceGroupControlPlane: resourceGroupControlPlane - storageService: storageService - subnetId: subnetResourceId - tags: tags - timeZone: timeZone } } +output applicationGroupResourceId string = applicationGroup.outputs.resourceId output dataCollectionRuleResourceId string = enableAvdInsights ? monitoring.outputs.dataCollectionRuleResourceId : '' output deploymentUserAssignedIdentityClientId string = deploymentUserAssignedIdentity.outputs.clientId output deploymentUserAssignedIdentityPrincipalId string = deploymentUserAssignedIdentity.outputs.principalId output deploymentUserAssignedIdentityResourceId string = deploymentUserAssignedIdentity.outputs.resourceId -output functionAppName string = fslogixStorageService == 'AzureFiles Premium' ? functionApp.outputs.functionAppName : '' +output diskAccessPolicyDefinitionId string = policy.outputs.policyDefinitionId +output diskAccessPolicyDisplayName string = policy.outputs.policyDisplayName +output diskAccessResourceId string = diskAccess.outputs.resourceId +output functionAppPrincipalId string = fslogixStorageService == 'AzureFiles Premium' ? functionApp.outputs.functionAppPrincipalId : '' +output hostPoolName string = hostPool.outputs.name +output hostPoolResourceId string = hostPool.outputs.resourceId output logAnalyticsWorkspaceName string = enableApplicationInsights || enableAvdInsights ? monitoring.outputs.logAnalyticsWorkspaceName : '' output logAnalyticsWorkspaceResourceId string = enableApplicationInsights || enableAvdInsights ? monitoring.outputs.logAnalyticsWorkspaceResourceId : '' output recoveryServicesVaultName string = recoveryServices ? recoveryServicesVault.outputs.name : '' +output resourceGroupName string = resourceGroup.name output virtualMachineName string = virtualMachine.outputs.name output virtualMachineResourceId string = virtualMachine.outputs.resourceId diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/monitoring.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/monitoring.bicep index 61c77a780..8490569b7 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/monitoring.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/monitoring.bicep @@ -1,13 +1,12 @@ param deploymentNameSuffix string param enableAvdInsights bool -param hostPoolName string +param hostPoolResourceId string param location string param logAnalyticsWorkspaceRetention int param logAnalyticsWorkspaceSku string param mlzTags object param namingConvention object param privateLinkScopeResourceId string -param resourceGroupControlPlane string param service string = 'mgmt' param serviceToken string param tags object @@ -15,9 +14,7 @@ param tags object resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = { name: replace(namingConvention.logAnalyticsWorkspace, serviceToken, service) location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.OperationalInsights/workspaces') ? tags['Microsoft.OperationalInsights/workspaces'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.OperationalInsights/workspaces'] ?? {}, mlzTags) properties: { sku: { name: logAnalyticsWorkspaceSku @@ -43,9 +40,7 @@ module privateLinkScope_logAnalyticsWorkspace 'privateLinkScope.bicep' = { resource dataCollectionRule 'Microsoft.Insights/dataCollectionRules@2022-06-01' = if (enableAvdInsights) { name: 'microsoft-avdi-${replace(namingConvention.dataCollectionRule, serviceToken, service)}' // The name must start with 'microsoft-avdi-' for proper integration with AVD Insights location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Insights/dataCollectionRules') ? tags['Microsoft.Insights/dataCollectionRules'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Insights/dataCollectionRules'] ?? {}, mlzTags) kind: 'Windows' properties: { dataSources: { @@ -131,9 +126,7 @@ resource dataCollectionRule 'Microsoft.Insights/dataCollectionRules@2022-06-01' resource dataCollectionEndpoint 'Microsoft.Insights/dataCollectionEndpoints@2021-04-01' = if (enableAvdInsights) { name: replace(namingConvention.dataCollectionEndpoint, serviceToken, service) location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Insights/dataCollectionEndpoints') ? tags['Microsoft.Insights/dataCollectionEndpoints'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Insights/dataCollectionEndpoints'] ?? {}, mlzTags) kind: 'Windows' properties: { networkAcls: { @@ -154,4 +147,3 @@ module privateLinkScope_dataCollectionEndpoint 'privateLinkScope.bicep' = if (en output logAnalyticsWorkspaceName string = logAnalyticsWorkspace.name output logAnalyticsWorkspaceResourceId string = logAnalyticsWorkspace.id output dataCollectionRuleResourceId string = enableAvdInsights ? dataCollectionRule.id : '' - diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/policy.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/policy.bicep index 6d0268c61..fc565c4a9 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/policy.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/policy.bicep @@ -83,3 +83,6 @@ module policyAssignment 'policyAssignment.bicep' = { policyName: policyDefinition.properties.displayName } } + +output policyDefinitionId string = policyDefinition.id +output policyDisplayName string = policyDefinition.properties.displayName diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/recoveryServicesVault.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/recoveryServicesVault.bicep index 07545a3fd..5e3d85ec8 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/recoveryServicesVault.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/recoveryServicesVault.bicep @@ -1,14 +1,13 @@ param azureBlobsPrivateDnsZoneResourceId string param azureQueueStoragePrivateDnsZoneResourceId string param deployFslogix bool -param hostPoolName string +param hostPoolResourceId string param location string param mlzTags object param recoveryServicesPrivateDnsZoneResourceId string param recoveryServicesVaultName string param recoveryServicesVaultNetworkInterfaceName string param recoveryServicesVaultPrivateEndpointName string -param resourceGroupControlPlane string param storageService string param subnetId string param tags object @@ -17,9 +16,7 @@ param timeZone string resource vault 'Microsoft.RecoveryServices/vaults@2022-03-01' = { name: recoveryServicesVaultName location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.RecoveryServices/vaults') ? tags['Microsoft.RecoveryServices/vaults'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.RecoveryServices/vaults'] ?? {}, mlzTags) sku: { name: 'RS0' tier: 'Standard' @@ -31,9 +28,7 @@ resource backupPolicy_Storage 'Microsoft.RecoveryServices/vaults/backupPolicies@ parent: vault name: 'AvdPolicyStorage' location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.RecoveryServices/vaults') ? tags['Microsoft.RecoveryServices/vaults'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.RecoveryServices/vaults'] ?? {}, mlzTags) properties: { backupManagementType: 'AzureStorage' schedulePolicy: { @@ -64,9 +59,7 @@ resource backupPolicy_Vm 'Microsoft.RecoveryServices/vaults/backupPolicies@2022- parent: vault name: 'AvdPolicyVm' location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.RecoveryServices/vaults') ? tags['Microsoft.RecoveryServices/vaults'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.RecoveryServices/vaults'] ?? {}, mlzTags) properties: { backupManagementType: 'AzureIaasVM' instantRpRetentionRangeInDays: 2 @@ -99,9 +92,7 @@ resource backupPolicy_Vm 'Microsoft.RecoveryServices/vaults/backupPolicies@2022- resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-04-01' = { name: recoveryServicesVaultPrivateEndpointName location: location - tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Network/privateEndpoints') ? tags['Microsoft.Network/privateEndpoints'] : {}, mlzTags) + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/privateEndpoints'] ?? {}, mlzTags) properties: { customNetworkInterfaceName: recoveryServicesVaultNetworkInterfaceName privateLinkServiceConnections: [ diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/scalingPlan.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/scalingPlan.bicep index 44b851d2f..b9f38bdbd 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/scalingPlan.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/scalingPlan.bicep @@ -232,13 +232,13 @@ resource scalingPlan 'Microsoft.DesktopVirtualization/scalingPlans@2023-09-05' = } } -resource schedules_Pooled 'Microsoft.DesktopVirtualization/scalingPlans/pooledSchedules@2024-04-03' = [for i in range(0, length(schedules)): if (hostPoolType == 'Pooled') { +resource schedules_Pooled 'Microsoft.DesktopVirtualization/scalingPlans/pooledSchedules@2023-09-05' = [for i in range(0, length(schedules)): if (hostPoolType == 'Pooled') { name: i == 0 ? 'Weekdays' : 'Weekends' parent: scalingPlan properties: schedules[i] }] -resource schedule_Personal 'Microsoft.DesktopVirtualization/scalingPlans/personalSchedules@2024-04-03' = [for i in range(0, length(schedules)): if (hostPoolType == 'Personal') { +resource schedule_Personal 'Microsoft.DesktopVirtualization/scalingPlans/personalSchedules@2023-09-05' = [for i in range(0, length(schedules)): if (hostPoolType == 'Personal') { name: i == 0 ? 'Weekdays' : 'Weekends' parent: scalingPlan properties: schedules[i] diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/management/virtualMachine.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/management/virtualMachine.bicep index ff432a965..3f6c64318 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/management/virtualMachine.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/management/virtualMachine.bicep @@ -7,32 +7,27 @@ param diskSku string param domainJoinPassword string param domainJoinUserPrincipalName string param domainName string -param hostPoolName string +param hostPoolResourceId string param location string param mlzTags object param networkInterfaceName string param organizationalUnitPath string -param resourceGroupControlPlane string -param subnet string +param subnetResourceId string param tags object param timestamp string = utcNow('yyyyMMddhhmmss') -param virtualNetwork string -param virtualNetworkResourceGroup string param virtualMachineName string @secure() param virtualMachinePassword string param virtualMachineUsername string -var tagsVirtualMachines = union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' -}, contains(tags, 'Microsoft.Compute/virtualMachines') ? tags['Microsoft.Compute/virtualMachines'] : {}, mlzTags) +var tagsVirtualMachines = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/virtualMachines'] ?? {}, mlzTags) resource networkInterface 'Microsoft.Network/networkInterfaces@2020-05-01' = { name: networkInterfaceName location: location tags: union({ - 'cm-resource-parent': '${subscription().id}}/resourceGroups/${resourceGroupControlPlane}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}' - }, contains(tags, 'Microsoft.Network/networkInterfaces') ? tags['Microsoft.Network/networkInterfaces'] : {}, mlzTags) + 'cm-resource-parent': hostPoolResourceId + }, tags[?'Microsoft.Network/networkInterfaces'] ?? {}, mlzTags) properties: { ipConfigurations: [ { @@ -40,7 +35,7 @@ resource networkInterface 'Microsoft.Network/networkInterfaces@2020-05-01' = { properties: { privateIPAllocationMethod: 'Dynamic' subnet: { - id: resourceId(virtualNetworkResourceGroup, 'Microsoft.Network/virtualNetworks/subnets', virtualNetwork, subnet) + id: subnetResourceId } primary: true privateIPAddressVersion: 'IPv4' diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/resourceGroup.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/resourceGroup.bicep deleted file mode 100644 index e689bc4f0..000000000 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/resourceGroup.bicep +++ /dev/null @@ -1,11 +0,0 @@ -targetScope = 'subscription' - -param location string -param resourceGroupName string -param tags object - -resource resourceGroup 'Microsoft.Resources/resourceGroups@2020-10-01' = { - name: resourceGroupName - location: location - tags: contains(tags, 'Microsoft.Resources/resourceGroups') ? tags['Microsoft.Resources/resourceGroups'] : {} -} diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/sessionHosts.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/sessionHosts.bicep index 05662d833..1161fe40b 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/sessionHosts.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/sessionHosts.bicep @@ -11,6 +11,9 @@ param deployFslogix bool param deploymentNameSuffix string param deploymentUserAssignedIdentityClientId string param deploymentUserAssignedIdentityPrincipalId string +param diskAccessPolicyDefinitionId string +param diskAccessPolicyDisplayName string +param diskAccessResourceId string param diskEncryptionSetResourceId string param diskSku string param divisionRemainderValue int @@ -21,6 +24,7 @@ param domainName string param drainMode bool param enableAcceleratedNetworking bool param enableAvdInsights bool +param enableRecoveryServices bool param environmentAbbreviation string param fslogixContainerType string param hostPoolName string @@ -39,12 +43,10 @@ param mlzTags object param namingConvention object param netAppFileShares array param organizationalUnitPath string -param enableRecoveryServices bool +param profile string param recoveryServicesVaultName string -param resourceGroupControlPlane string -param resourceGroupHosts string param resourceGroupManagement string -param roleDefinitions object +param resourceGroupName string param scalingWeekdaysOffPeakStartTime string param scalingWeekdaysPeakStartTime string param scalingWeekendsOffPeakStartTime string @@ -67,34 +69,51 @@ param virtualMachineSize string param virtualMachineUsername string var availabilitySetNamePrefix = namingConvention.availabilitySet -var tagsAvailabilitySets = union({'cm-resource-parent': '${subscription().id}/resourceGroups/${resourceGroupManagement}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Compute/availabilitySets') ? tags['Microsoft.Compute/availabilitySets'] : {}, mlzTags) -var tagsNetworkInterfaces = union({'cm-resource-parent': '${subscription().id}/resourceGroups/${resourceGroupManagement}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Network/networkInterfaces') ? tags['Microsoft.Network/networkInterfaces'] : {}, mlzTags) -var tagsRecoveryServicesVault = union({'cm-resource-parent': '${subscription().id}/resourceGroups/${resourceGroupManagement}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.recoveryServices/vaults') ? tags['Microsoft.recoveryServices/vaults'] : {}, mlzTags) -var tagsVirtualMachines = union({'cm-resource-parent': '${subscription().id}/resourceGroups/${resourceGroupManagement}/providers/Microsoft.DesktopVirtualization/hostpools/${hostPoolName}'}, contains(tags, 'Microsoft.Compute/virtualMachines') ? tags['Microsoft.Compute/virtualMachines'] : {}, mlzTags) +var tagsVirtualMachines = union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/virtualMachines'] ?? {}, mlzTags) var uniqueToken = uniqueString(identifier, environmentAbbreviation, subscription().subscriptionId) var virtualMachineNamePrefix = replace(namingConvention.virtualMachine, serviceToken, '') +resource rg 'Microsoft.Resources/resourceGroups@2023-07-01' = { + name: resourceGroupName + location: location + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Resources/resourceGroups'] ?? {}, mlzTags) +} + +// Sets an Azure policy to disable public network access to managed disks +module policyAssignment '../management/policyAssignment.bicep' = { + name: 'assign-policy-diskAccess-${deploymentNameSuffix}' + scope: rg + params: { + diskAccessResourceId: diskAccessResourceId + location: location + policyDefinitionId: diskAccessPolicyDefinitionId + policyDisplayName: diskAccessPolicyDisplayName + policyName: diskAccessPolicyDisplayName + } +} + module availabilitySets 'availabilitySets.bicep' = if (hostPoolType == 'Pooled' && availability == 'AvailabilitySets') { - name: 'deploy-avail-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupHosts) + name: 'deploy-avSets-${deploymentNameSuffix}' + scope: rg params: { availabilitySetNamePrefix: availabilitySetNamePrefix availabilitySetsCount: availabilitySetsCount availabilitySetsIndex: availabilitySetsIndex location: location - tagsAvailabilitySets: tagsAvailabilitySets + tagsAvailabilitySets: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Compute/availabilitySets'] ?? {}, mlzTags) } } -// Role Assignment for Virtual Machine Login User -// This module deploys the role assignments to login to Azure AD joined session hosts -module roleAssignments '../common/roleAssignments/resourceGroup.bicep' = [for i in range(0, length(securityPrincipalObjectIds)): if (!contains(activeDirectorySolution, 'DomainServices')) { - name: 'deploy-role-assignments-${i}-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupHosts) +// Role Assignment for Entra Joined Virtual Machines +// Purpose: assigns the Virtual Machine Login User role on the hosts resource group +// to enable the login to Entra joined virtual machines +module roleAssignments '../common/roleAssignments/resourceGroup.bicep' = [for i in range(0, length(securityPrincipalObjectIds)): if (contains(activeDirectorySolution, 'EntraId')) { + name: 'assign-role-${i}-${deploymentNameSuffix}' + scope: rg params: { principalId: securityPrincipalObjectIds[i] principalType: 'Group' - roleDefinitionId: roleDefinitions.VirtualMachineUserLogin + roleDefinitionId: 'fb879df8-f326-4884-b1cf-06f3ad86be52' } }] @@ -110,7 +129,7 @@ resource image 'Microsoft.Compute/galleries/images@2023-07-03' existing = if (em // Disable Autoscale if adding new session hosts to an existing host pool module disableAutoscale '../common/runCommand.bicep' = { - name: 'deploy-disable-autoscale-${deploymentNameSuffix}' + name: 'deploy-disableAutoscale-${deploymentNameSuffix}' scope: resourceGroup(resourceGroupManagement) params: { location: location @@ -147,10 +166,52 @@ module disableAutoscale '../common/runCommand.bicep' = { } } +// Set MarketPlace Terms for ESRI's ArcGIS Pro image +module setMarketplaceTerms '../common/runCommand.bicep' = if (profile == 'ArcGISPro') { + name: 'set-marketplaceTerms-${deploymentNameSuffix}' + scope: resourceGroup(resourceGroupManagement) + params: { + location: location + name: 'Set-AzureMarketplaceTerms' + parameters: [ + { + name: 'ImageOffer' + value: imageOffer + } + { + name: 'ImagePublisher' + value: imagePublisher + } + { + name: 'ImageSku' + value: imageSku + } + { + name: 'ResourceManagerUri' + value: environment().resourceManager + } + { + name: 'SubscriptionId' + value: subscription().subscriptionId + } + { + name: 'UserAssignedidentityClientId' + value: deploymentUserAssignedIdentityClientId + } + ] + script: loadTextContent('../../artifacts/Set-AzureMarketplaceTerms.ps1') + tags: tagsVirtualMachines + virtualMachineName: managementVirtualMachineName + } + dependsOn: [ + disableAutoscale + ] +} + @batchSize(1) module virtualMachines 'virtualMachines.bicep' = [for i in range(1, sessionHostBatchCount): { name: 'deploy-vms-${i - 1}-${deploymentNameSuffix}' - scope: resourceGroup(resourceGroupHosts) + scope: rg params: { activeDirectorySolution: activeDirectorySolution availability: availability @@ -183,7 +244,7 @@ module virtualMachines 'virtualMachines.bicep' = [for i in range(1, sessionHostB netAppFileShares: netAppFileShares networkInterfaceNamePrefix: namingConvention.virtualMachineNetworkInterface organizationalUnitPath: organizationalUnitPath - resourceGroupControlPlane: resourceGroupControlPlane + profile: profile resourceGroupManagement: resourceGroupManagement serviceToken: serviceToken sessionHostCount: i == sessionHostBatchCount && divisionRemainderValue > 0 ? divisionRemainderValue : maxResourcesPerTemplateDeployment @@ -194,7 +255,7 @@ module virtualMachines 'virtualMachines.bicep' = [for i in range(1, sessionHostB storageService: storageService storageSuffix: storageSuffix subnetResourceId: subnetResourceId - tagsNetworkInterfaces: tagsNetworkInterfaces + tagsNetworkInterfaces: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.Network/networkInterfaces'] ?? {}, mlzTags) tagsVirtualMachines: tagsVirtualMachines uniqueToken: uniqueToken virtualMachineNamePrefix: virtualMachineNamePrefix @@ -205,11 +266,12 @@ module virtualMachines 'virtualMachines.bicep' = [for i in range(1, sessionHostB dependsOn: [ availabilitySets disableAutoscale + setMarketplaceTerms ] }] module recoveryServices 'recoveryServices.bicep' = if (enableRecoveryServices && hostPoolType == 'Personal') { - name: 'deploy-recovery-services-${deploymentNameSuffix}' + name: 'deploy-recoveryServices-${deploymentNameSuffix}' scope: resourceGroup(resourceGroupManagement) params: { deployFslogix: deployFslogix @@ -218,11 +280,11 @@ module recoveryServices 'recoveryServices.bicep' = if (enableRecoveryServices && location: location maxResourcesPerTemplateDeployment: maxResourcesPerTemplateDeployment recoveryServicesVaultName: recoveryServicesVaultName - resourceGroupHosts: resourceGroupHosts + resourceGroupHosts: rg.name resourceGroupManagement: resourceGroupManagement sessionHostBatchCount: sessionHostBatchCount sessionHostIndex: sessionHostIndex - tagsRecoveryServicesVault: tagsRecoveryServicesVault + tagsRecoveryServicesVault: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.recoveryServices/vaults'] ?? {}, mlzTags) virtualMachineNamePrefix: virtualMachineNamePrefix } dependsOn: [ @@ -231,7 +293,7 @@ module recoveryServices 'recoveryServices.bicep' = if (enableRecoveryServices && } module scalingPlan '../management/scalingPlan.bicep' = { - name: 'deploy-scaling-plan-${deploymentNameSuffix}' + name: 'deploy-scalingPlan-${deploymentNameSuffix}' scope: resourceGroup(resourceGroupManagement) params: { deploymentUserAssignedIdentityPrincipalId: deploymentUserAssignedIdentityPrincipalId @@ -242,7 +304,7 @@ module scalingPlan '../management/scalingPlan.bicep' = { logAnalyticsWorkspaceResourceId: logAnalyticsWorkspaceResourceId scalingPlanDiagnosticSettingName: namingConvention.scalingPlanDiagnosticSetting scalingPlanName: namingConvention.scalingPlan - tags: tags + tags: union({'cm-resource-parent': hostPoolResourceId}, tags[?'Microsoft.DesktopVirtualization/scalingPlans'] ?? {}, mlzTags) timeZone: timeZone weekdaysOffPeakStartTime: scalingWeekdaysOffPeakStartTime weekdaysPeakStartTime: scalingWeekdaysPeakStartTime diff --git a/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/virtualMachines.bicep b/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/virtualMachines.bicep index 6cba20cb0..5584da0a7 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/virtualMachines.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/modules/sessionHosts/virtualMachines.bicep @@ -30,7 +30,7 @@ param managementVirtualMachineName string param netAppFileShares array param networkInterfaceNamePrefix string param organizationalUnitPath string -param resourceGroupControlPlane string +param profile string param resourceGroupManagement string param serviceToken string param sessionHostCount int @@ -97,7 +97,7 @@ var storageAccountToken = '${storageAccountPrefix}??' // The token is used for A resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' existing = { name: hostPoolName - scope: resourceGroup(subscription().subscriptionId, resourceGroupControlPlane) + scope: resourceGroup(subscription().subscriptionId, resourceGroupManagement) } resource networkInterface 'Microsoft.Network/networkInterfaces@2020-05-01' = [for i in range(0, sessionHostCount): { @@ -130,6 +130,11 @@ resource virtualMachine 'Microsoft.Compute/virtualMachines@2021-03-01' = [for i identity: { type: 'SystemAssigned' // Required for Entra join } + plan: profile == 'ArcGISPro' ? { + name: imageSku + publisher: imagePublisher + product: imageOffer + } : null zones: availability == 'AvailabilityZones' ? [ availabilityZones[i % length(availabilityZones)] ] : null @@ -397,7 +402,7 @@ module drainMode '../common/runCommand.bicep' = if (enableDrainMode) { } { name: 'HostPoolResourceGroupName' - value: resourceGroupControlPlane + value: resourceGroupManagement } { name: 'ResourceManagerUri' diff --git a/src/bicep/add-ons/azure-virtual-desktop/solution.bicep b/src/bicep/add-ons/azure-virtual-desktop/solution.bicep index 8ec64a176..d01785a2d 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/solution.bicep +++ b/src/bicep/add-ons/azure-virtual-desktop/solution.bicep @@ -220,6 +220,15 @@ param scalingWeekendsPeakStartTime string = '09:00' @description('The array of Security Principals with their object IDs and display names to assign to the AVD Application Group and FSLogix Storage.') param securityPrincipals array +/* Example of a security principal +[ + { + displayName: 'AVD' + objectId: '00000000-0000-0000-0000-000000000000' + } +] +*/ + @maxValue(5000) @minValue(0) @description('The number of session hosts to deploy in the host pool. Ensure you have the approved quota to deploy the desired count.') @@ -333,24 +342,6 @@ var fileShareNames = { var fileShares = fileShareNames[fslogixContainerType] var netbios = split(domainName, '.')[0] var privateDnsZoneResourceIdPrefix = '/subscriptions/${split(hubVirtualNetworkResourceId, '/')[2]}/resourceGroups/${split(hubVirtualNetworkResourceId, '/')[4]}/providers/Microsoft.Network/privateDnsZones/' -var resourceGroupServices = union( - [ - 'controlPlane' - 'hosts' - 'management' - ], - deployFslogix - ? [ - 'storage' - ] - : [] -) -var roleDefinitions = { - DesktopVirtualizationPowerOnOffContributor: '40c5ff49-9181-41f8-ae61-143b0e78555e' - DesktopVirtualizationUser: '1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63' - Reader: 'acdd72a7-3385-48ef-bd42-f606fba81ae7' - VirtualMachineUserLogin: 'fb879df8-f326-4884-b1cf-06f3ad86be52' -} var storageSku = fslogixStorageService == 'None' ? 'None' : split(fslogixStorageService, ' ')[1] var storageService = split(fslogixStorageService, ' ')[0] var storageSuffix = environment().suffixes.storage @@ -385,19 +376,19 @@ var subnets = { : [] } -// Gets the hub virtual network for its location and tags +// Gets the MLZ hub virtual network for its location and tags resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-11-01' existing = { name: split(hubVirtualNetworkResourceId, '/')[8] scope: resourceGroup(split(hubVirtualNetworkResourceId, '/')[2], split(hubVirtualNetworkResourceId, '/')[4]) } -// Gets the application group references if the feed workspace already exists +// Gets the application group references if the AVD feed workspace already exists resource workspace 'Microsoft.DesktopVirtualization/workspaces@2023-09-05' existing = if (!empty(existingFeedWorkspaceResourceId)) { scope: resourceGroup(split(existingFeedWorkspaceResourceId, '/')[2], split(existingFeedWorkspaceResourceId, '/')[4]) name: split(existingFeedWorkspaceResourceId, '/')[8] } -// This module deploys telemetry for ArcGIS Pro deployments +// Optionally deploys telemetry for ArcGIS Pro deployments #disable-next-line no-deployments-resources resource partnerTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableTelemetry && profile == 'ArcGISPro') { name: 'pid-4e82be1d-7fcb-4913-a90c-aa84d7ea3a1c' @@ -412,22 +403,9 @@ resource partnerTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } } -// This deployment is used to get the naming convention and tokens for the resource groups and resources. -module naming_controlPlane '../../modules/naming-convention.bicep' = { - name: 'get-naming-cp-${deploymentNameSuffix}' - params: { - environmentAbbreviation: environmentAbbreviation - location: virtualNetwork.location - networkName: 'avd' - networkShortName: 'avd' - resourcePrefix: identifier - stampIndex: string(stampIndex) - } -} - -// This deployment is used to get the naming convention and tokens for the resource groups and resources. -module naming_hub '../../modules/naming-convention.bicep' = { - name: 'get-naming-hub-${deploymentNameSuffix}' +// Gets the naming convention and tokens for the resource groups and resources +module naming_management '../../modules/naming-convention.bicep' = { + name: 'get-naming-mgmt-${deploymentNameSuffix}' params: { environmentAbbreviation: environmentAbbreviation location: virtualNetwork.location @@ -465,28 +443,18 @@ module tier3_hosts '../tier3/solution.bicep' = { } } -// Resource Groups -module rgs '../../modules/resource-group.bicep' = [ - for service in resourceGroupServices: { - name: 'deploy-rg-${service}-${deploymentNameSuffix}' - params: { - location: service == 'controlPlane' ? virtualNetwork.location : locationVirtualMachines - mlzTags: tier3_hosts.outputs.mlzTags - name: service == 'controlPlane' - ? replace(naming_controlPlane.outputs.names.resourceGroup, naming_controlPlane.outputs.tokens.service, service) - : replace(tier3_hosts.outputs.namingConvention.resourceGroup, tier3_hosts.outputs.tokens.service, service) - tags: tags - } - } -] - -// Management Services: AVD Insights, File Share Scaling, Scaling Tool +// Management: host pool, app group, AVD Insights, File Share Scaling module management 'modules/management/management.bicep' = { name: 'deploy-management-${deploymentNameSuffix}' params: { + activeDirectorySolution: activeDirectorySolution avdObjectId: avdObjectId + avdPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(tier3_hosts.outputs.privateDnsZones, name => startsWith(name, 'privatelink.wvd'))[0]}' + customImageId: customImageId + customRdpProperty: customRdpProperty deployFslogix: deployFslogix deploymentNameSuffix: deploymentNameSuffix + desktopFriendlyName: empty(desktopFriendlyName) ? string(stampIndex) : desktopFriendlyName diskEncryptionSetResourceId: tier3_hosts.outputs.diskEncryptionSetResourceId diskSku: diskSku domainJoinPassword: domainJoinPassword @@ -496,9 +464,17 @@ module management 'modules/management/management.bicep' = { enableAvdInsights: enableAvdInsights environmentAbbreviation: environmentAbbreviation fslogixStorageService: fslogixStorageService + hostPoolPublicNetworkAccess: hostPoolPublicNetworkAccess + hostPoolType: hostPoolType + imageOffer: imageOffer + imagePublisher: imagePublisher + imageSku: imageSku + imageVersionResourceId: imageVersionResourceId + locationControlPlane: virtualNetwork.location locationVirtualMachines: locationVirtualMachines logAnalyticsWorkspaceRetention: logAnalyticsWorkspaceRetention logAnalyticsWorkspaceSku: logAnalyticsWorkspaceSku + maxSessionLimit: usersPerCore * virtualMachineVirtualCpuCount mlzTags: tier3_hosts.outputs.mlzTags namingConvention: tier3_hosts.outputs.namingConvention organizationalUnitPath: organizationalUnitPath @@ -508,72 +484,25 @@ module management 'modules/management/management.bicep' = { recoveryServices: recoveryServices recoveryServicesGeo: tier3_hosts.outputs.locationProperties.recoveryServicesGeo resourceAbbreviations: tier3_hosts.outputs.resourceAbbreviations - resourceGroupControlPlane: rgs[0].outputs.name - resourceGroupHosts: rgs[1].outputs.name - resourceGroupManagement: rgs[2].outputs.name - resourceGroupStorage: deployFslogix - ? replace(tier3_hosts.outputs.namingConvention.resourceGroup, tier3_hosts.outputs.tokens.service, 'storage') - : '' - roleDefinitions: roleDefinitions - serviceToken: tier3_hosts.outputs.tokens.service - storageService: storageService - subnetResourceId: tier3_hosts.outputs.subnets[0].id - subnets: tier3_hosts.outputs.subnets - tags: tags - timeDifference: tier3_hosts.outputs.locationProperties.timeDifference - timeZone: tier3_hosts.outputs.locationProperties.timeZone - virtualMachinePassword: virtualMachinePassword - virtualMachineUsername: virtualMachineUsername - } -} - -// AVD Control Plane -// This module deploys the host pool and desktop application group -module controlPlane 'modules/controlPlane/controlPlane.bicep' = { - name: 'deploy-control-plane-${deploymentNameSuffix}' - params: { - activeDirectorySolution: activeDirectorySolution - avdPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(tier3_hosts.outputs.privateDnsZones, name => startsWith(name, 'privatelink.wvd'))[0]}' - customImageId: customImageId - customRdpProperty: customRdpProperty - deploymentNameSuffix: deploymentNameSuffix - deploymentUserAssignedIdentityClientId: management.outputs.deploymentUserAssignedIdentityClientId - deploymentUserAssignedIdentityPrincipalId: management.outputs.deploymentUserAssignedIdentityPrincipalId - desktopFriendlyName: empty(desktopFriendlyName) ? string(stampIndex) : desktopFriendlyName - diskSku: diskSku - domainName: domainName - enableAvdInsights: enableAvdInsights - hostPoolPublicNetworkAccess: hostPoolPublicNetworkAccess - hostPoolType: hostPoolType - imageOffer: imageOffer - imagePublisher: imagePublisher - imageSku: imageSku - imageVersionResourceId: imageVersionResourceId - locationControlPlane: virtualNetwork.location - locationVirtualMachines: locationVirtualMachines - logAnalyticsWorkspaceResourceId: enableAvdInsights ? management.outputs.logAnalyticsWorkspaceResourceId : '' - managementVirtualMachineName: management.outputs.virtualMachineName - maxSessionLimit: usersPerCore * virtualMachineVirtualCpuCount - mlzTags: tier3_hosts.outputs.mlzTags - namingConvention: naming_controlPlane.outputs.names - resourceGroupControlPlane: rgs[0].outputs.name - resourceGroupManagement: rgs[2].outputs.name - roleDefinitions: roleDefinitions + resourceGroupName: replace(naming_management.outputs.names.resourceGroup, naming_management.outputs.tokens.service, 'management') + resourceGroupProfiles: replace(tier3_hosts.outputs.namingConvention.resourceGroup, tier3_hosts.outputs.tokens.service, 'profiles') securityPrincipalObjectIds: map(securityPrincipals, item => item.objectId) - serviceToken: naming_controlPlane.outputs.tokens.service + serviceToken: tier3_hosts.outputs.tokens.service sessionHostNamePrefix: replace( tier3_hosts.outputs.namingConvention.virtualMachine, tier3_hosts.outputs.tokens.service, '' ) - subnetResourceId: tier3_hosts.outputs.subnets[1].id + storageService: storageService + subnetResourceId: tier3_hosts.outputs.subnets[0].id + subnets: tier3_hosts.outputs.subnets tags: tags + timeZone: tier3_hosts.outputs.locationProperties.timeZone validationEnvironment: validationEnvironment + virtualMachinePassword: virtualMachinePassword virtualMachineSize: virtualMachineSize + virtualMachineUsername: virtualMachineUsername } - dependsOn: [ - rgs - ] } // AVD Workspaces @@ -582,7 +511,7 @@ module workspaces 'modules/sharedServices/sharedServices.bicep' = { name: 'deploy-workspaces-${deploymentNameSuffix}' scope: subscription(split(sharedServicesSubnetResourceId, '/')[2]) params: { - applicationGroupResourceId: controlPlane.outputs.applicationGroupResourceId + applicationGroupResourceId: management.outputs.applicationGroupResourceId avdPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(tier3_hosts.outputs.privateDnsZones, name => startsWith(name, 'privatelink.wvd'))[0]}' deploymentNameSuffix: deploymentNameSuffix deploymentUserAssignedIdentityClientId: management.outputs.deploymentUserAssignedIdentityClientId @@ -593,84 +522,40 @@ module workspaces 'modules/sharedServices/sharedServices.bicep' = { : workspace.properties.applicationGroupReferences existingFeedWorkspaceResourceId: existingFeedWorkspaceResourceId existingWorkspace: !empty(existingFeedWorkspaceResourceId) - hostPoolName: controlPlane.outputs.hostPoolName + hostPoolName: management.outputs.hostPoolName locationControlPlane: virtualNetwork.location locationVirtualMachines: locationVirtualMachines logAnalyticsWorkspaceResourceId: management.outputs.logAnalyticsWorkspaceResourceId managementVirtualMachineName: management.outputs.virtualMachineName mlzTags: tier3_hosts.outputs.mlzTags - resourceGroupManagement: rgs[2].outputs.name + resourceGroupManagement: management.outputs.resourceGroupName sharedServicesSubnetResourceId: sharedServicesSubnetResourceId tags: tags - workspaceFeedDiagnoticSettingName: replace( - replace(naming_hub.outputs.names.workspaceFeedDiagnosticSetting, naming_hub.outputs.tokens.service, 'feed'), - '-${stampIndex}', - '' - ) - workspaceFeedName: replace( - replace(naming_controlPlane.outputs.names.workspaceFeed, naming_controlPlane.outputs.tokens.service, 'feed'), - '-${stampIndex}', - '' - ) - workspaceFeedNetworkInterfaceName: replace( - replace(naming_hub.outputs.names.workspaceFeedNetworkInterface, naming_hub.outputs.tokens.service, 'feed'), - '-${stampIndex}', - '' - ) - workspaceFeedPrivateEndpointName: replace( - replace(naming_hub.outputs.names.workspaceFeedPrivateEndpoint, naming_hub.outputs.tokens.service, 'feed'), - '-${stampIndex}', - '' - ) + workspaceFeedDiagnoticSettingName: naming_management.outputs.names.workspaceFeedDiagnosticSetting + workspaceFeedName: naming_management.outputs.names.workspaceFeed + workspaceFeedNetworkInterfaceName: naming_management.outputs.names.workspaceFeedNetworkInterface + workspaceFeedPrivateEndpointName: naming_management.outputs.names.workspaceFeedPrivateEndpoint workspaceFeedResourceGroupName: replace( replace( - naming_controlPlane.outputs.names.resourceGroup, - naming_controlPlane.outputs.tokens.service, + naming_management.outputs.names.resourceGroup, + naming_management.outputs.tokens.service, 'feedWorkspace' ), '-${stampIndex}', '' ) workspaceFriendlyName: empty(workspaceFriendlyName) - ? replace( - replace(naming_controlPlane.outputs.names.workspaceFeed, '-${naming_controlPlane.outputs.tokens.service}', ''), - '-${stampIndex}', - '' - ) + ? replace(naming_management.outputs.names.workspaceFeed, '-${naming_management.outputs.tokens.service}', '') : '${workspaceFriendlyName} (${virtualNetwork.location})' - workspaceGlobalName: replace( - replace( - replace(naming_controlPlane.outputs.names.workspaceGlobal, naming_controlPlane.outputs.tokens.service, 'global'), - '-${stampIndex}', - '' - ), - identifier, - virtualNetwork.tags.resourcePrefix - ) - workspaceGlobalNetworkInterfaceName: replace( - replace( - replace(naming_hub.outputs.names.workspaceGlobalNetworkInterface, naming_hub.outputs.tokens.service, 'global'), - '-${stampIndex}', - '' - ), - identifier, - virtualNetwork.tags.resourcePrefix - ) + workspaceGlobalName: replace(naming_management.outputs.names.workspaceGlobal, identifier, virtualNetwork.tags.resourcePrefix) + workspaceGlobalNetworkInterfaceName: replace(naming_management.outputs.names.workspaceGlobalNetworkInterface, identifier, virtualNetwork.tags.resourcePrefix) workspaceGlobalPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(tier3_hosts.outputs.privateDnsZones, name => startsWith(name, 'privatelink-global.wvd'))[0]}' - workspaceGlobalPrivateEndpointName: replace( - replace( - replace(naming_hub.outputs.names.workspaceGlobalPrivateEndpoint, naming_hub.outputs.tokens.service, 'global'), - '-${stampIndex}', - '' - ), - identifier, - virtualNetwork.tags.resourcePrefix - ) + workspaceGlobalPrivateEndpointName: replace(naming_management.outputs.names.workspaceGlobalPrivateEndpoint, identifier, virtualNetwork.tags.resourcePrefix) workspaceGlobalResourceGroupName: replace( replace( replace( - naming_controlPlane.outputs.names.resourceGroup, - naming_controlPlane.outputs.tokens.service, + naming_management.outputs.names.resourceGroup, + naming_management.outputs.tokens.service, 'globalWorkspace' ), '-${stampIndex}', @@ -691,6 +576,7 @@ module fslogix 'modules/fslogix/fslogix.bicep' = if (deployFslogix) { azureFilesPrivateDnsZoneResourceId: '${privateDnsZoneResourceIdPrefix}${filter(tier3_hosts.outputs.privateDnsZones, name => contains(name, 'file'))[0]}' deploymentNameSuffix: deploymentNameSuffix deploymentUserAssignedIdentityClientId: management.outputs.deploymentUserAssignedIdentityClientId + deploymentUserAssignedIdentityPrincipalId: management.outputs.deploymentUserAssignedIdentityPrincipalId dnsServers: string(tier3_hosts.outputs.dnsServers) domainJoinPassword: domainJoinPassword domainJoinUserPrincipalName: domainJoinUserPrincipalName @@ -701,7 +587,8 @@ module fslogix 'modules/fslogix/fslogix.bicep' = if (deployFslogix) { fslogixContainerType: fslogixContainerType fslogixShareSizeInGB: fslogixShareSizeInGB fslogixStorageService: fslogixStorageService - functionAppName: management.outputs.functionAppName + functionAppPrincipalId: management.outputs.functionAppPrincipalId + hostPoolResourceId: management.outputs.hostPoolResourceId keyVaultUri: tier3_hosts.outputs.keyVaultUri location: locationVirtualMachines managementVirtualMachineName: management.outputs.virtualMachineName @@ -710,10 +597,9 @@ module fslogix 'modules/fslogix/fslogix.bicep' = if (deployFslogix) { netbios: netbios organizationalUnitPath: organizationalUnitPath recoveryServices: recoveryServices - resourceGroupControlPlane: rgs[0].outputs.name - resourceGroupManagement: rgs[2].outputs.name - resourceGroupStorage: deployFslogix ? rgs[3].outputs.name : '' - securityPrincipalNames: map(securityPrincipals, item => item.name) + resourceGroupManagement: management.outputs.resourceGroupName + resourceGroupName: replace(tier3_hosts.outputs.namingConvention.resourceGroup, tier3_hosts.outputs.tokens.service, 'profiles') + securityPrincipalNames: map(securityPrincipals, item => item.displayName) securityPrincipalObjectIds: map(securityPrincipals, item => item.objectId) serviceToken: tier3_hosts.outputs.tokens.service smbServerLocation: tier3_hosts.outputs.locationProperties.timeZone @@ -726,10 +612,6 @@ module fslogix 'modules/fslogix/fslogix.bicep' = if (deployFslogix) { subnets: tier3_hosts.outputs.subnets tags: tags } - dependsOn: [ - controlPlane - rgs - ] } module sessionHosts 'modules/sessionHosts/sessionHosts.bicep' = { @@ -746,6 +628,9 @@ module sessionHosts 'modules/sessionHosts/sessionHosts.bicep' = { deploymentNameSuffix: deploymentNameSuffix deploymentUserAssignedIdentityClientId: management.outputs.deploymentUserAssignedIdentityClientId deploymentUserAssignedIdentityPrincipalId: management.outputs.deploymentUserAssignedIdentityPrincipalId + diskAccessPolicyDefinitionId: management.outputs.diskAccessPolicyDefinitionId + diskAccessPolicyDisplayName: management.outputs.diskAccessPolicyDisplayName + diskAccessResourceId: management.outputs.diskAccessResourceId diskEncryptionSetResourceId: tier3_hosts.outputs.diskEncryptionSetResourceId diskSku: diskSku divisionRemainderValue: divisionRemainderValue @@ -758,8 +643,8 @@ module sessionHosts 'modules/sessionHosts/sessionHosts.bicep' = { enableRecoveryServices: recoveryServices environmentAbbreviation: environmentAbbreviation fslogixContainerType: fslogixContainerType - hostPoolName: controlPlane.outputs.hostPoolName - hostPoolResourceId: controlPlane.outputs.hostPoolResourceId + hostPoolName: management.outputs.hostPoolName + hostPoolResourceId: management.outputs.hostPoolResourceId hostPoolType: hostPoolType identifier: identifier imageOffer: imageOffer @@ -776,11 +661,10 @@ module sessionHosts 'modules/sessionHosts/sessionHosts.bicep' = { 'None' ] organizationalUnitPath: organizationalUnitPath + profile: profile recoveryServicesVaultName: management.outputs.recoveryServicesVaultName - resourceGroupControlPlane: rgs[0].outputs.name - resourceGroupHosts: rgs[1].outputs.name - resourceGroupManagement: rgs[2].outputs.name - roleDefinitions: roleDefinitions + resourceGroupManagement: management.outputs.resourceGroupName + resourceGroupName: replace(tier3_hosts.outputs.namingConvention.resourceGroup, tier3_hosts.outputs.tokens.service, 'hosts') scalingWeekdaysOffPeakStartTime: scalingWeekdaysOffPeakStartTime scalingWeekdaysPeakStartTime: scalingWeekdaysPeakStartTime scalingWeekendsOffPeakStartTime: scalingWeekendsOffPeakStartTime @@ -803,7 +687,6 @@ module sessionHosts 'modules/sessionHosts/sessionHosts.bicep' = { } dependsOn: [ fslogix - rgs ] } @@ -812,7 +695,7 @@ module cleanUp 'modules/cleanUp/cleanUp.bicep' = { params: { deploymentNameSuffix: deploymentNameSuffix location: locationVirtualMachines - resourceGroupManagement: rgs[2].outputs.name + resourceGroupManagement: management.outputs.resourceGroupName userAssignedIdentityClientId: management.outputs.deploymentUserAssignedIdentityClientId virtualMachineResourceId: management.outputs.virtualMachineResourceId } diff --git a/src/bicep/add-ons/azure-virtual-desktop/solution.json b/src/bicep/add-ons/azure-virtual-desktop/solution.json index 10c417380..d9109271c 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/solution.json +++ b/src/bicep/add-ons/azure-virtual-desktop/solution.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "495118660330348734" + "version": "0.31.92.45157", + "templateHash": "8358069094561879230" } }, "parameters": { @@ -593,13 +593,6 @@ "fileShares": "[variables('fileShareNames')[parameters('fslogixContainerType')]]", "netbios": "[split(parameters('domainName'), '.')[0]]", "privateDnsZoneResourceIdPrefix": "[format('/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/privateDnsZones/', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4])]", - "resourceGroupServices": "[union(createArray('controlPlane', 'hosts', 'management'), if(variables('deployFslogix'), createArray('storage'), createArray()))]", - "roleDefinitions": { - "DesktopVirtualizationPowerOnOffContributor": "40c5ff49-9181-41f8-ae61-143b0e78555e", - "DesktopVirtualizationUser": "1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63", - "Reader": "acdd72a7-3385-48ef-bd42-f606fba81ae7", - "VirtualMachineUserLogin": "fb879df8-f326-4884-b1cf-06f3ad86be52" - }, "storageSku": "[if(equals(parameters('fslogixStorageService'), 'None'), 'None', split(parameters('fslogixStorageService'), ' ')[1])]", "storageService": "[split(parameters('fslogixStorageService'), ' ')[0]]", "storageSuffix": "[environment().suffixes.storage]", @@ -635,7 +628,7 @@ { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))]", + "name": "[format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))]", "location": "[deployment().location]", "properties": { "expressionEvaluationOptions": { @@ -668,8 +661,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "11992572431768878515" + "version": "0.31.92.45157", + "templateHash": "11125044402666498605" } }, "parameters": { @@ -1136,7 +1129,7 @@ "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", "names": { "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", - "applicationGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationGroups)]", + "applicationGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-desktop', variables('resourceAbbreviations').applicationGroups))]", "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", @@ -1209,14 +1202,14 @@ "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", - "workspaceFeed": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobal": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" + "workspaceFeed": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobal": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" } }, "resources": [], @@ -1244,7 +1237,7 @@ { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))]", + "name": "[format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))]", "location": "[deployment().location]", "properties": { "expressionEvaluationOptions": { @@ -1252,23 +1245,68 @@ }, "mode": "Incremental", "parameters": { + "additionalSubnets": { + "value": "[union(variables('subnets').avdControlPlane, variables('subnets').azureNetAppFiles, variables('subnets').functionApp)]" + }, + "deployActivityLogDiagnosticSetting": { + "value": "[parameters('deployActivityLogDiagnosticSetting')]" + }, + "deployDefender": { + "value": "[parameters('deployDefender')]" + }, + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "deployNetworkWatcher": { + "value": "[parameters('deployNetworkWatcher')]" + }, + "deployPolicy": { + "value": "[parameters('deployPolicy')]" + }, + "emailSecurityContact": { + "value": "[parameters('emailSecurityContact')]" + }, "environmentAbbreviation": { "value": "[parameters('environmentAbbreviation')]" }, - "location": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location]" - }, - "networkName": { - "value": "avd" + "firewallResourceId": { + "value": "[parameters('hubAzureFirewallResourceId')]" }, - "networkShortName": { - "value": "avd" + "hubVirtualNetworkResourceId": { + "value": "[parameters('hubVirtualNetworkResourceId')]" }, - "resourcePrefix": { + "identifier": { "value": "[parameters('identifier')]" }, + "location": { + "value": "[parameters('locationVirtualMachines')]" + }, + "logAnalyticsWorkspaceResourceId": { + "value": "[parameters('operationsLogAnalyticsWorkspaceResourceId')]" + }, + "policy": { + "value": "[parameters('policy')]" + }, "stampIndex": { "value": "[string(parameters('stampIndex'))]" + }, + "subnetName": { + "value": "AvdSessionHosts" + }, + "subnetAddressPrefix": { + "value": "[parameters('subnetAddressPrefixes')[0]]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "virtualNetworkAddressPrefix": { + "value": "[parameters('virtualNetworkAddressPrefixes')[0]]" + }, + "workloadName": { + "value": "avd" + }, + "workloadShortName": { + "value": "avd" } }, "template": { @@ -1277,5473 +1315,2337 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "11992572431768878515" + "version": "0.31.92.45157", + "templateHash": "14266827690996546891" } }, "parameters": { + "additionalSubnets": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "An array of additional subnets to support the tier3 workload." + } + }, + "deployActivityLogDiagnosticSetting": { + "type": "bool", + "metadata": { + "description": "Choose whether to deploy a diagnostic setting for the Activity Log." + } + }, + "deployDefender": { + "type": "bool", + "metadata": { + "description": "Choose whether to deploy Defender for Cloud." + } + }, + "deploymentNameSuffix": { + "type": "string", + "defaultValue": "[utcNow()]", + "metadata": { + "description": "The suffix to append to the deployment name. It defaults to the current UTC date and time." + } + }, + "deployNetworkWatcher": { + "type": "bool", + "metadata": { + "description": "Choose whether to deploy Network Watcher for the deployment location." + } + }, + "deployPolicy": { + "type": "bool", + "metadata": { + "description": "Choose whether to deploy a policy assignment." + } + }, + "emailSecurityContact": { + "type": "string", + "metadata": { + "description": "The email address to use for Defender for Cloud notifications." + } + }, "environmentAbbreviation": { - "type": "string" + "type": "string", + "defaultValue": "dev", + "allowedValues": [ + "dev", + "prod", + "test" + ], + "metadata": { + "description": "The abbreviation for the environment." + } + }, + "firewallResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Azure Firewall in the HUB." + } + }, + "hubVirtualNetworkResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the HUB Virtual Network." + } + }, + "identifier": { + "type": "string", + "maxLength": 3, + "metadata": { + "description": "The identifier for the resource names. This value should represent the workload, project, or business unit." + } + }, + "keyVaultDiagnosticsLogs": { + "type": "array", + "defaultValue": [ + { + "category": "AuditEvent", + "enabled": true + }, + { + "category": "AzurePolicyEvaluationDetails", + "enabled": true + } + ], + "metadata": { + "description": "An array of Key Vault Diagnostic Logs categories to collect. See \"https://learn.microsoft.com/en-us/azure/key-vault/general/logging?tabs=Vault\" for valid values." + } }, "location": { - "type": "string" + "type": "string", + "defaultValue": "[deployment().location]", + "metadata": { + "description": "The location for the deployment. It defaults to the location of the deployment." + } }, - "networkName": { - "type": "string" + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Log Analytics Workspace to use for log storage." + } }, - "networkShortName": { - "type": "string" + "logStorageSkuName": { + "type": "string", + "defaultValue": "Standard_GRS", + "metadata": { + "description": "The Storage Account SKU to use for log storage. It defaults to \"Standard_GRS\". See https://docs.microsoft.com/en-us/rest/api/storagerp/srp_sku_types for valid settings." + } }, - "resourcePrefix": { - "type": "string" + "networkSecurityGroupDiagnosticsLogs": { + "type": "array", + "defaultValue": [ + { + "category": "NetworkSecurityGroupEvent", + "enabled": true + }, + { + "category": "NetworkSecurityGroupRuleCounter", + "enabled": true + } + ], + "metadata": { + "description": "An array of Network Security Group diagnostic logs to apply to the workload Virtual Network. See https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-nsg-manage-log#log-categories for valid settings." + } + }, + "networkSecurityGroupDiagnosticsMetrics": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "The metrics to monitor for the Network Security Group." + } + }, + "networkSecurityGroupRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "The rules to apply to the Network Security Group." + } + }, + "policy": { + "type": "string", + "defaultValue": "NISTRev4", + "metadata": { + "description": "The policy to assign to the workload." + } }, "stampIndex": { "type": "string", - "defaultValue": "" + "defaultValue": "", + "metadata": { + "description": "The stamp index allows for multiple AVD stamps with the same business unit or project to support different use cases." + } }, - "tokens": { + "subnetAddressPrefix": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The address prefix for the workload subnet." + } + }, + "subnetName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The custom name for the workload subnet if the naming convention is not desired. Subnets are child resources and do not require a unique name between virtual networks, only within the same virtual network." + } + }, + "tags": { "type": "object", - "defaultValue": { - "purpose": "purpose_token", - "resource": "resource_token", - "service": "service_token" + "defaultValue": {}, + "metadata": { + "description": "The tags to apply to the resources." } - } - }, - "variables": { - "$fxv#0": { - "AzureChina": { - "chinaeast": { - "abbreviation": "cne", - "recoveryServicesGeo": "sha", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "chinaeast2": { - "abbreviation": "cne2", - "recoveryServicesGeo": "sha2", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "chinanorth": { - "abbreviation": "cnn", - "recoveryServicesGeo": "bjb", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "chinanorth2": { - "abbreviation": "cnn2", - "recoveryServicesGeo": "bjb2", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - } - }, - "AzureCloud": { - "australiacentral": { - "abbreviation": "auc", - "recoveryServicesGeo": "acl", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "australiacentral2": { - "abbreviation": "auc2", - "recoveryServicesGeo": "acl2", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "australiaeast": { - "abbreviation": "aue", - "recoveryServicesGeo": "ae", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "australiasoutheast": { - "abbreviation": "ause", - "recoveryServicesGeo": "ase", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "brazilsouth": { - "abbreviation": "brs", - "recoveryServicesGeo": "brs", - "timeDifference": "-3:00", - "timeZone": "E. South America Standard Time" - }, - "brazilsoutheast": { - "abbreviation": "brse", - "recoveryServicesGeo": "bse", - "timeDifference": "-3:00", - "timeZone": "E. South America Standard Time" - }, - "canadacentral": { - "abbreviation": "cac", - "recoveryServicesGeo": "cnc", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "canadaeast": { - "abbreviation": "cae", - "recoveryServicesGeo": "cne", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "centralindia": { - "abbreviation": "inc", - "recoveryServicesGeo": "inc", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "centralus": { - "abbreviation": "usc", - "recoveryServicesGeo": "cus", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "eastasia": { - "abbreviation": "ase", - "recoveryServicesGeo": "ea", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "eastus": { - "abbreviation": "use", - "recoveryServicesGeo": "eus", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "eastus2": { - "abbreviation": "use2", - "recoveryServicesGeo": "eus2", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "francecentral": { - "abbreviation": "frc", - "recoveryServicesGeo": "frc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "francesouth": { - "abbreviation": "frs", - "recoveryServicesGeo": "frs", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "germanynorth": { - "abbreviation": "den", - "recoveryServicesGeo": "gn", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "germanywestcentral": { - "abbreviation": "dewc", - "recoveryServicesGeo": "gwc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "israelcentral": { - "abbreviation": "ilc", - "recoveryServicesGeo": "ilc", - "timeDifference": "+2:00", - "timeZone": "Israel Standard Time" - }, - "italynorth": { - "abbreviation": "itn", - "recoveryServicesGeo": "itn", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "japaneast": { - "abbreviation": "jpe", - "recoveryServicesGeo": "jpe", - "timeDifference": "+9:00", - "timeZone": "Tokyo Standard Time" - }, - "japanwest": { - "abbreviation": "jpw", - "recoveryServicesGeo": "jpw", - "timeDifference": "+9:00", - "timeZone": "Tokyo Standard Time" - }, - "jioindiacentral": { - "abbreviation": "injc", - "recoveryServicesGeo": "jic", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "jioindiawest": { - "abbreviation": "injw", - "recoveryServicesGeo": "jiw", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "koreacentral": { - "abbreviation": "krc", - "recoveryServicesGeo": "krc", - "timeDifference": "+9:00", - "timeZone": "Korea Standard Time" + }, + "virtualNetworkAddressPrefix": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The address prefix for the workload Virtual Network." + } + }, + "virtualNetworkDiagnosticsLogs": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "The diagnostic logs to apply to the workload Virtual Network." + } + }, + "virtualNetworkDiagnosticsMetrics": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "The metrics to monitor for the workload Virtual Network." + } + }, + "workloadName": { + "type": "string", + "defaultValue": "tier3", + "minLength": 1, + "maxLength": 10, + "metadata": { + "description": "The name for the workload." + } + }, + "workloadShortName": { + "type": "string", + "defaultValue": "t3", + "minLength": 1, + "maxLength": 3, + "metadata": { + "description": "The short name for the workload." + } + } + }, + "variables": { + "hubResourceGroupName": "[split(parameters('hubVirtualNetworkResourceId'), '/')[4]]", + "hubSubscriptionId": "[split(parameters('hubVirtualNetworkResourceId'), '/')[2]]", + "subscriptionId": "[subscription().subscriptionId]" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" }, - "koreasouth": { - "abbreviation": "krs", - "recoveryServicesGeo": "krs", - "timeDifference": "+9:00", - "timeZone": "Korea Standard Time" + "mode": "Incremental", + "parameters": { + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "environmentAbbreviation": { + "value": "[parameters('environmentAbbreviation')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "networks": { + "value": [ + { + "name": "[parameters('workloadName')]", + "shortName": "[parameters('workloadShortName')]", + "deployUniqueResources": false, + "subscriptionId": "[variables('subscriptionId')]", + "nsgDiagLogs": "[parameters('networkSecurityGroupDiagnosticsLogs')]", + "nsgDiagMetrics": "[parameters('networkSecurityGroupDiagnosticsMetrics')]", + "nsgRules": "[parameters('networkSecurityGroupRules')]", + "vnetAddressPrefix": "[parameters('virtualNetworkAddressPrefix')]", + "vnetDiagLogs": "[parameters('virtualNetworkDiagnosticsLogs')]", + "vnetDiagMetrics": "[parameters('virtualNetworkDiagnosticsMetrics')]", + "subnetAddressPrefix": "[parameters('subnetAddressPrefix')]" + } + ] + }, + "resourcePrefix": { + "value": "[parameters('identifier')]" + }, + "stampIndex": { + "value": "[parameters('stampIndex')]" + } }, - "northcentralus": { - "abbreviation": "usnc", - "recoveryServicesGeo": "ncus", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "northeurope": { - "abbreviation": "eun", - "recoveryServicesGeo": "ne", - "timeDifference": "0:00", - "timeZone": "GMT Standard Time" - }, - "norwayeast": { - "abbreviation": "noe", - "recoveryServicesGeo": "nwe", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "norwaywest": { - "abbreviation": "now", - "recoveryServicesGeo": "nww", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "polandcentral": { - "abbreviation": "plc", - "recoveryServicesGeo": "plc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "qatarcentral": { - "abbreviation": "qac", - "recoveryServicesGeo": "qac", - "timeDifference": "+3:00", - "timeZone": "Arabian Standard Time" - }, - "southafricanorth": { - "abbreviation": "zan", - "recoveryServicesGeo": "san", - "timeDifference": "+2:00", - "timeZone": "South Africa Standard Time" - }, - "southafricawest": { - "abbreviation": "zaw", - "recoveryServicesGeo": "saw", - "timeDifference": "+2:00", - "timeZone": "South Africa Standard Time" - }, - "southcentralus": { - "abbreviation": "ussc", - "recoveryServicesGeo": "scus", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "southeastasia": { - "abbreviation": "asse", - "recoveryServicesGeo": "sea", - "timeDifference": "+8:00", - "timeZone": "Singapore Standard Time" - }, - "southindia": { - "abbreviation": "ins", - "recoveryServicesGeo": "ins", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "swedencentral": { - "abbreviation": "sec", - "recoveryServicesGeo": "sdc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "switzerlandnorth": { - "abbreviation": "chn", - "recoveryServicesGeo": "szn", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "switzerlandwest": { - "abbreviation": "chw", - "recoveryServicesGeo": "szw", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "uaecentral": { - "abbreviation": "aec", - "recoveryServicesGeo": "uac", - "timeDifference": "+3:00", - "timeZone": "Arabian Standard Time" - }, - "uaenorth": { - "abbreviation": "aen", - "recoveryServicesGeo": "uan", - "timeDifference": "+3:00", - "timeZone": "Arabian Standard Time" - }, - "uksouth": { - "abbreviation": "uks", - "recoveryServicesGeo": "uks", - "timeDifference": "0:00", - "timeZone": "GMT Standard Time" - }, - "ukwest": { - "abbreviation": "ukw", - "recoveryServicesGeo": "ukw", - "timeDifference": "0:00", - "timeZone": "GMT Standard Time" - }, - "westcentralus": { - "abbreviation": "uswc", - "recoveryServicesGeo": "wcus", - "timeDifference": "-7:00", - "timeZone": "Mountain Standard Time" - }, - "westeurope": { - "abbreviation": "euw", - "recoveryServicesGeo": "we", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "westindia": { - "abbreviation": "inw", - "recoveryServicesGeo": "inw", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "westus": { - "abbreviation": "usw", - "recoveryServicesGeo": "wus", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - }, - "westus2": { - "abbreviation": "usw2", - "recoveryServicesGeo": "wus2", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - }, - "westus3": { - "abbreviation": "usw3", - "recoveryServicesGeo": "wus3", - "timeDifference": "-7:00", - "timeZone": "Mountain Standard Time" - } - }, - "AzureUSGovernment": { - "usdodcentral": { - "abbreviation": "dodc", - "recoveryServicesGeo": "udc", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "usdodeast": { - "abbreviation": "dode", - "recoveryServicesGeo": "ude", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "usgovarizona": { - "abbreviation": "az", - "recoveryServicesGeo": "uga", - "timeDifference": "-7:00", - "timeZone": "Mountain Standard Time" - }, - "usgovtexas": { - "abbreviation": "tx", - "recoveryServicesGeo": "ugt", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "usgovvirginia": { - "abbreviation": "va", - "recoveryServicesGeo": "ugv", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - } - }, - "USNat": { - "usnateast": { - "abbreviation": "east", - "recoveryServicesGeo": "exe", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "usnatwest": { - "abbreviation": "west", - "recoveryServicesGeo": "exw", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - } - }, - "USSec": { - "usseceast": { - "abbreviation": "east", - "recoveryServicesGeo": "rxe", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "ussecwest": { - "abbreviation": "west", - "recoveryServicesGeo": "rxw", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - } - } - }, - "$fxv#1": { - "actionGroups": "ag", - "applicationGroups": "vdag", - "applicationInsights": "appi", - "appServicePlans": "asp", - "automationAccounts": "aa", - "availabilitySets": "avail", - "azureFirewalls": "afw", - "bastionHosts": "bas", - "computeGallieries": "cg", - "dataCollectionEndpoints": "dce", - "dataCollectionRuleAssociations": "dcra", - "dataCollectionRules": "dcr", - "diagnosticSettings": "diag", - "diskAccesses": "da", - "diskEncryptionSets": "des", - "disks": "disk", - "firewallPolicies": "afwp", - "functionApps": "func", - "hostPools": "vdpool", - "ipConfigurations": "ipconf", - "keyVaults": "kv", - "logAnalyticsWorkspaces": "log", - "netAppAccounts": "naa", - "netAppCapacityPools": "nacp", - "networkInterfaces": "nic", - "networkSecurityGroups": "nsg", - "networkWatchers": "nw", - "privateEndpoints": "pe", - "privateLinkScopes": "pls", - "publicIPAddresses": "pip", - "recoveryServicesVaults": "rsv", - "remoteApplicationGroups": "vdag", - "resourceGroups": "rg", - "routeTables": "rt", - "scalingPlans": "vdscaling", - "storageAccounts": "st", - "subnets": "snet", - "userAssignedIdentities": "id", - "virtualMachines": "vm", - "virtualNetworks": "vnet", - "workspaces": "vdws" - }, - "locations": "[variables('$fxv#0')[environment().name]]", - "locationAbbreviation": "[variables('locations')[parameters('location')].abbreviation]", - "resourceAbbreviations": "[variables('$fxv#1')]", - "namingConvention": "[format('{0}-{1}{2}-{3}-{4}-{5}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", - "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", - "names": { - "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", - "applicationGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationGroups)]", - "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", - "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", - "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", - "automationAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", - "automationAccountNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", - "automationAccountPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", - "availabilitySet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').availabilitySets)]", - "azureFirewall": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').azureFirewalls)]", - "azureFirewallClientPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, format('client-{0}', variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallClientPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-client-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').azureFirewalls)]", - "azureFirewallManagementPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, format('mgmt-{0}', variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallManagementPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-mgmt-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallPolicy": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').firewallPolicies)]", - "bastionHost": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostNetworkSecurityGroup": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkSecurityGroups), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').bastionHosts))]", - "computeGallery": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').computeGallieries), '-', '_')]", - "dataCollectionEndpoint": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionEndpoints)]", - "dataCollectionRuleAssociation": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionRuleAssociations)]", - "dataCollectionRule": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionRules)]", - "diskAccess": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').diskAccesses)]", - "diskAccessNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').diskAccesses)]", - "diskAccessPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').diskAccesses)]", - "diskEncryptionSet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').diskEncryptionSets)]", - "functionApp": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').functionApps)]", - "functionAppNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').functionApps, parameters('tokens').service))]", - "functionAppPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').functionApps, parameters('tokens').service))]", - "hostPool": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').hostPools)]", - "hostPoolDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", - "hostPoolNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", - "hostPoolPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", - "keyVault": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').keyVaults), '-', ''), parameters('networkName'), parameters('networkShortName'))]", - "keyVaultDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", - "keyVaultNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", - "keyVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", - "logAnalyticsWorkspace": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').logAnalyticsWorkspaces)]", - "logAnalyticsWorkspaceDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').logAnalyticsWorkspaces)]", - "netAppAccountCapacityPool": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').netAppCapacityPools)]", - "netAppAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').netAppAccounts)]", - "networkSecurityGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').networkSecurityGroups)]", - "networkSecurityGroupDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').networkSecurityGroups)]", - "networkWatcher": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').networkWatchers)]", - "privateLinkScope": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').privateLinkScopes)]", - "privateLinkScopeNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').privateLinkScopes)]", - "privateLinkScopePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').privateLinkScopes)]", - "recoveryServicesVault": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').recoveryServicesVaults)]", - "recoveryServicesVaultNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", - "recoveryServicesVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", - "resourceGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').resourceGroups)]", - "routeTable": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').routeTables)]", - "scalingPlan": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').scalingPlans)]", - "scalingPlanDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').scalingPlans)]", - "storageAccount": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').storageAccounts), parameters('networkName'), parameters('networkShortName'))]", - "storageAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').storageAccounts))]", - "storageAccountBlobNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountFileNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-file', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountQueueNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-queue', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountTableNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-table', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountBlobPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountFilePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-file', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountQueuePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-queue', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountTablePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-table', variables('resourceAbbreviations').storageAccounts))]", - "subnet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').subnets)]", - "userAssignedIdentity": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').userAssignedIdentities)]", - "virtualMachine": "[replace(replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').virtualMachines), parameters('environmentAbbreviation'), first(parameters('environmentAbbreviation'))), parameters('networkName'), ''), '-', '')]", - "virtualMachineDisk": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').disks), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", - "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", - "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", - "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", - "workspaceFeed": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobal": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" - } - }, - "resources": [], - "outputs": { - "locations": { - "type": "object", - "value": "[variables('locations')]" - }, - "names": { - "type": "object", - "value": "[variables('names')]" - }, - "resourceAbbreviations": { - "type": "object", - "value": "[variables('resourceAbbreviations')]" - }, - "tokens": { - "type": "object", - "value": "[parameters('tokens')]" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "additionalSubnets": { - "value": "[union(variables('subnets').avdControlPlane, variables('subnets').azureNetAppFiles, variables('subnets').functionApp)]" - }, - "deployActivityLogDiagnosticSetting": { - "value": "[parameters('deployActivityLogDiagnosticSetting')]" - }, - "deployDefender": { - "value": "[parameters('deployDefender')]" - }, - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "deployNetworkWatcher": { - "value": "[parameters('deployNetworkWatcher')]" - }, - "deployPolicy": { - "value": "[parameters('deployPolicy')]" - }, - "emailSecurityContact": { - "value": "[parameters('emailSecurityContact')]" - }, - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" - }, - "firewallResourceId": { - "value": "[parameters('hubAzureFirewallResourceId')]" - }, - "hubVirtualNetworkResourceId": { - "value": "[parameters('hubVirtualNetworkResourceId')]" - }, - "identifier": { - "value": "[parameters('identifier')]" - }, - "location": { - "value": "[parameters('locationVirtualMachines')]" - }, - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('operationsLogAnalyticsWorkspaceResourceId')]" - }, - "policy": { - "value": "[parameters('policy')]" - }, - "stampIndex": { - "value": "[string(parameters('stampIndex'))]" - }, - "subnetName": { - "value": "AvdSessionHosts" - }, - "subnetAddressPrefix": { - "value": "[parameters('subnetAddressPrefixes')[0]]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "virtualNetworkAddressPrefix": { - "value": "[parameters('virtualNetworkAddressPrefixes')[0]]" - }, - "workloadName": { - "value": "avd" - }, - "workloadShortName": { - "value": "avd" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "9467495710159860030" - } - }, - "parameters": { - "additionalSubnets": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "An array of additional subnets to support the tier3 workload." - } - }, - "deployActivityLogDiagnosticSetting": { - "type": "bool", - "metadata": { - "description": "Choose whether to deploy a diagnostic setting for the Activity Log." - } - }, - "deployDefender": { - "type": "bool", - "metadata": { - "description": "Choose whether to deploy Defender for Cloud." - } - }, - "deploymentNameSuffix": { - "type": "string", - "defaultValue": "[utcNow()]", - "metadata": { - "description": "The suffix to append to the deployment name. It defaults to the current UTC date and time." - } - }, - "deployNetworkWatcher": { - "type": "bool", - "metadata": { - "description": "Choose whether to deploy Network Watcher for the deployment location." - } - }, - "deployPolicy": { - "type": "bool", - "metadata": { - "description": "Choose whether to deploy a policy assignment." - } - }, - "emailSecurityContact": { - "type": "string", - "metadata": { - "description": "The email address to use for Defender for Cloud notifications." - } - }, - "environmentAbbreviation": { - "type": "string", - "defaultValue": "dev", - "allowedValues": [ - "dev", - "prod", - "test" - ], - "metadata": { - "description": "The abbreviation for the environment." - } - }, - "firewallResourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Azure Firewall in the HUB." - } - }, - "hubVirtualNetworkResourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the HUB Virtual Network." - } - }, - "identifier": { - "type": "string", - "maxLength": 3, - "metadata": { - "description": "The identifier for the resource names. This value should represent the workload, project, or business unit." - } - }, - "keyVaultDiagnosticsLogs": { - "type": "array", - "defaultValue": [ - { - "category": "AuditEvent", - "enabled": true - }, - { - "category": "AzurePolicyEvaluationDetails", - "enabled": true - } - ], - "metadata": { - "description": "An array of Key Vault Diagnostic Logs categories to collect. See \"https://learn.microsoft.com/en-us/azure/key-vault/general/logging?tabs=Vault\" for valid values." - } - }, - "location": { - "type": "string", - "defaultValue": "[deployment().location]", - "metadata": { - "description": "The location for the deployment. It defaults to the location of the deployment." - } - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "metadata": { - "description": "The resource ID of the Log Analytics Workspace to use for log storage." - } - }, - "logStorageSkuName": { - "type": "string", - "defaultValue": "Standard_GRS", - "metadata": { - "description": "The Storage Account SKU to use for log storage. It defaults to \"Standard_GRS\". See https://docs.microsoft.com/en-us/rest/api/storagerp/srp_sku_types for valid settings." - } - }, - "networkSecurityGroupDiagnosticsLogs": { - "type": "array", - "defaultValue": [ - { - "category": "NetworkSecurityGroupEvent", - "enabled": true - }, - { - "category": "NetworkSecurityGroupRuleCounter", - "enabled": true - } - ], - "metadata": { - "description": "An array of Network Security Group diagnostic logs to apply to the workload Virtual Network. See https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-nsg-manage-log#log-categories for valid settings." - } - }, - "networkSecurityGroupDiagnosticsMetrics": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "The metrics to monitor for the Network Security Group." - } - }, - "networkSecurityGroupRules": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "The rules to apply to the Network Security Group." - } - }, - "policy": { - "type": "string", - "defaultValue": "NISTRev4", - "metadata": { - "description": "The policy to assign to the workload." - } - }, - "stampIndex": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The stamp index allows for multiple AVD stamps with the same business unit or project to support different use cases." - } - }, - "subnetAddressPrefix": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The address prefix for the workload subnet." - } - }, - "subnetName": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The custom name for the workload subnet if the naming convention is not desired. Subnets are child resources and do not require a unique name between virtual networks, only within the same virtual network." - } - }, - "tags": { - "type": "object", - "defaultValue": {}, - "metadata": { - "description": "The tags to apply to the resources." - } - }, - "virtualNetworkAddressPrefix": { - "type": "string", - "defaultValue": "", - "metadata": { - "description": "The address prefix for the workload Virtual Network." - } - }, - "virtualNetworkDiagnosticsLogs": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "The diagnostic logs to apply to the workload Virtual Network." - } - }, - "virtualNetworkDiagnosticsMetrics": { - "type": "array", - "defaultValue": [], - "metadata": { - "description": "The metrics to monitor for the workload Virtual Network." - } - }, - "workloadName": { - "type": "string", - "defaultValue": "tier3", - "minLength": 1, - "maxLength": 10, - "metadata": { - "description": "The name for the workload." - } - }, - "workloadShortName": { - "type": "string", - "defaultValue": "t3", - "minLength": 1, - "maxLength": 3, - "metadata": { - "description": "The short name for the workload." - } - } - }, - "variables": { - "hubResourceGroupName": "[split(parameters('hubVirtualNetworkResourceId'), '/')[4]]", - "hubSubscriptionId": "[split(parameters('hubVirtualNetworkResourceId'), '/')[2]]", - "subscriptionId": "[subscription().subscriptionId]" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "networks": { - "value": [ - { - "name": "[parameters('workloadName')]", - "shortName": "[parameters('workloadShortName')]", - "deployUniqueResources": false, - "subscriptionId": "[variables('subscriptionId')]", - "nsgDiagLogs": "[parameters('networkSecurityGroupDiagnosticsLogs')]", - "nsgDiagMetrics": "[parameters('networkSecurityGroupDiagnosticsMetrics')]", - "nsgRules": "[parameters('networkSecurityGroupRules')]", - "vnetAddressPrefix": "[parameters('virtualNetworkAddressPrefix')]", - "vnetDiagLogs": "[parameters('virtualNetworkDiagnosticsLogs')]", - "vnetDiagMetrics": "[parameters('virtualNetworkDiagnosticsMetrics')]", - "subnetAddressPrefix": "[parameters('subnetAddressPrefix')]" - } - ] - }, - "resourcePrefix": { - "value": "[parameters('identifier')]" - }, - "stampIndex": { - "value": "[parameters('stampIndex')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "10924801470287352076" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "environmentAbbreviation": { - "type": "string" - }, - "location": { - "type": "string" - }, - "networks": { - "type": "array" - }, - "resourcePrefix": { - "type": "string" - }, - "stampIndex": { - "type": "string", - "defaultValue": "" - } - }, - "variables": { - "$fxv#0": "1.0.0", - "environmentName": { - "dev": "Development", - "prod": "Production", - "test": "Test" - }, - "mlzTags": { - "environment": "[variables('environmentName')[parameters('environmentAbbreviation')]]", - "landingZoneName": "MissionLandingZone", - "landingZoneVersion": "[variables('$fxv#0')]", - "resourcePrefix": "[parameters('resourcePrefix')]" - } - }, - "resources": [ - { - "copy": { - "name": "namingConventions", - "count": "[length(parameters('networks'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('naming-convention-{0}-{1}', parameters('networks')[copyIndex()].shortName, parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "networkName": { - "value": "[parameters('networks')[copyIndex()].name]" - }, - "networkShortName": { - "value": "[parameters('networks')[copyIndex()].shortName]" - }, - "resourcePrefix": { - "value": "[parameters('resourcePrefix')]" - }, - "stampIndex": { - "value": "[parameters('stampIndex')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "11992572431768878515" - } - }, - "parameters": { - "environmentAbbreviation": { - "type": "string" - }, - "location": { - "type": "string" - }, - "networkName": { - "type": "string" - }, - "networkShortName": { - "type": "string" - }, - "resourcePrefix": { - "type": "string" - }, - "stampIndex": { - "type": "string", - "defaultValue": "" - }, - "tokens": { - "type": "object", - "defaultValue": { - "purpose": "purpose_token", - "resource": "resource_token", - "service": "service_token" - } - } - }, - "variables": { - "$fxv#0": { - "AzureChina": { - "chinaeast": { - "abbreviation": "cne", - "recoveryServicesGeo": "sha", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "chinaeast2": { - "abbreviation": "cne2", - "recoveryServicesGeo": "sha2", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "chinanorth": { - "abbreviation": "cnn", - "recoveryServicesGeo": "bjb", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "chinanorth2": { - "abbreviation": "cnn2", - "recoveryServicesGeo": "bjb2", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - } - }, - "AzureCloud": { - "australiacentral": { - "abbreviation": "auc", - "recoveryServicesGeo": "acl", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "australiacentral2": { - "abbreviation": "auc2", - "recoveryServicesGeo": "acl2", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "australiaeast": { - "abbreviation": "aue", - "recoveryServicesGeo": "ae", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "australiasoutheast": { - "abbreviation": "ause", - "recoveryServicesGeo": "ase", - "timeDifference": "+10:00", - "timeZone": "AUS Eastern Standard Time" - }, - "brazilsouth": { - "abbreviation": "brs", - "recoveryServicesGeo": "brs", - "timeDifference": "-3:00", - "timeZone": "E. South America Standard Time" - }, - "brazilsoutheast": { - "abbreviation": "brse", - "recoveryServicesGeo": "bse", - "timeDifference": "-3:00", - "timeZone": "E. South America Standard Time" - }, - "canadacentral": { - "abbreviation": "cac", - "recoveryServicesGeo": "cnc", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "canadaeast": { - "abbreviation": "cae", - "recoveryServicesGeo": "cne", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "centralindia": { - "abbreviation": "inc", - "recoveryServicesGeo": "inc", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "centralus": { - "abbreviation": "usc", - "recoveryServicesGeo": "cus", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "eastasia": { - "abbreviation": "ase", - "recoveryServicesGeo": "ea", - "timeDifference": "+8:00", - "timeZone": "China Standard Time" - }, - "eastus": { - "abbreviation": "use", - "recoveryServicesGeo": "eus", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "eastus2": { - "abbreviation": "use2", - "recoveryServicesGeo": "eus2", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "francecentral": { - "abbreviation": "frc", - "recoveryServicesGeo": "frc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "francesouth": { - "abbreviation": "frs", - "recoveryServicesGeo": "frs", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "germanynorth": { - "abbreviation": "den", - "recoveryServicesGeo": "gn", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "germanywestcentral": { - "abbreviation": "dewc", - "recoveryServicesGeo": "gwc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "israelcentral": { - "abbreviation": "ilc", - "recoveryServicesGeo": "ilc", - "timeDifference": "+2:00", - "timeZone": "Israel Standard Time" - }, - "italynorth": { - "abbreviation": "itn", - "recoveryServicesGeo": "itn", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "japaneast": { - "abbreviation": "jpe", - "recoveryServicesGeo": "jpe", - "timeDifference": "+9:00", - "timeZone": "Tokyo Standard Time" - }, - "japanwest": { - "abbreviation": "jpw", - "recoveryServicesGeo": "jpw", - "timeDifference": "+9:00", - "timeZone": "Tokyo Standard Time" - }, - "jioindiacentral": { - "abbreviation": "injc", - "recoveryServicesGeo": "jic", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "jioindiawest": { - "abbreviation": "injw", - "recoveryServicesGeo": "jiw", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "koreacentral": { - "abbreviation": "krc", - "recoveryServicesGeo": "krc", - "timeDifference": "+9:00", - "timeZone": "Korea Standard Time" - }, - "koreasouth": { - "abbreviation": "krs", - "recoveryServicesGeo": "krs", - "timeDifference": "+9:00", - "timeZone": "Korea Standard Time" - }, - "northcentralus": { - "abbreviation": "usnc", - "recoveryServicesGeo": "ncus", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "northeurope": { - "abbreviation": "eun", - "recoveryServicesGeo": "ne", - "timeDifference": "0:00", - "timeZone": "GMT Standard Time" - }, - "norwayeast": { - "abbreviation": "noe", - "recoveryServicesGeo": "nwe", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "norwaywest": { - "abbreviation": "now", - "recoveryServicesGeo": "nww", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "polandcentral": { - "abbreviation": "plc", - "recoveryServicesGeo": "plc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "qatarcentral": { - "abbreviation": "qac", - "recoveryServicesGeo": "qac", - "timeDifference": "+3:00", - "timeZone": "Arabian Standard Time" - }, - "southafricanorth": { - "abbreviation": "zan", - "recoveryServicesGeo": "san", - "timeDifference": "+2:00", - "timeZone": "South Africa Standard Time" - }, - "southafricawest": { - "abbreviation": "zaw", - "recoveryServicesGeo": "saw", - "timeDifference": "+2:00", - "timeZone": "South Africa Standard Time" - }, - "southcentralus": { - "abbreviation": "ussc", - "recoveryServicesGeo": "scus", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "southeastasia": { - "abbreviation": "asse", - "recoveryServicesGeo": "sea", - "timeDifference": "+8:00", - "timeZone": "Singapore Standard Time" - }, - "southindia": { - "abbreviation": "ins", - "recoveryServicesGeo": "ins", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "swedencentral": { - "abbreviation": "sec", - "recoveryServicesGeo": "sdc", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "switzerlandnorth": { - "abbreviation": "chn", - "recoveryServicesGeo": "szn", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "switzerlandwest": { - "abbreviation": "chw", - "recoveryServicesGeo": "szw", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "uaecentral": { - "abbreviation": "aec", - "recoveryServicesGeo": "uac", - "timeDifference": "+3:00", - "timeZone": "Arabian Standard Time" - }, - "uaenorth": { - "abbreviation": "aen", - "recoveryServicesGeo": "uan", - "timeDifference": "+3:00", - "timeZone": "Arabian Standard Time" - }, - "uksouth": { - "abbreviation": "uks", - "recoveryServicesGeo": "uks", - "timeDifference": "0:00", - "timeZone": "GMT Standard Time" - }, - "ukwest": { - "abbreviation": "ukw", - "recoveryServicesGeo": "ukw", - "timeDifference": "0:00", - "timeZone": "GMT Standard Time" - }, - "westcentralus": { - "abbreviation": "uswc", - "recoveryServicesGeo": "wcus", - "timeDifference": "-7:00", - "timeZone": "Mountain Standard Time" - }, - "westeurope": { - "abbreviation": "euw", - "recoveryServicesGeo": "we", - "timeDifference": "+1:00", - "timeZone": "Central Europe Standard Time" - }, - "westindia": { - "abbreviation": "inw", - "recoveryServicesGeo": "inw", - "timeDifference": "+5:30", - "timeZone": "India Standard Time" - }, - "westus": { - "abbreviation": "usw", - "recoveryServicesGeo": "wus", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - }, - "westus2": { - "abbreviation": "usw2", - "recoveryServicesGeo": "wus2", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - }, - "westus3": { - "abbreviation": "usw3", - "recoveryServicesGeo": "wus3", - "timeDifference": "-7:00", - "timeZone": "Mountain Standard Time" - } - }, - "AzureUSGovernment": { - "usdodcentral": { - "abbreviation": "dodc", - "recoveryServicesGeo": "udc", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "usdodeast": { - "abbreviation": "dode", - "recoveryServicesGeo": "ude", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "usgovarizona": { - "abbreviation": "az", - "recoveryServicesGeo": "uga", - "timeDifference": "-7:00", - "timeZone": "Mountain Standard Time" - }, - "usgovtexas": { - "abbreviation": "tx", - "recoveryServicesGeo": "ugt", - "timeDifference": "-6:00", - "timeZone": "Central Standard Time" - }, - "usgovvirginia": { - "abbreviation": "va", - "recoveryServicesGeo": "ugv", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - } - }, - "USNat": { - "usnateast": { - "abbreviation": "east", - "recoveryServicesGeo": "exe", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "usnatwest": { - "abbreviation": "west", - "recoveryServicesGeo": "exw", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - } - }, - "USSec": { - "usseceast": { - "abbreviation": "east", - "recoveryServicesGeo": "rxe", - "timeDifference": "-5:00", - "timeZone": "Eastern Standard Time" - }, - "ussecwest": { - "abbreviation": "west", - "recoveryServicesGeo": "rxw", - "timeDifference": "-8:00", - "timeZone": "Pacific Standard Time" - } - } - }, - "$fxv#1": { - "actionGroups": "ag", - "applicationGroups": "vdag", - "applicationInsights": "appi", - "appServicePlans": "asp", - "automationAccounts": "aa", - "availabilitySets": "avail", - "azureFirewalls": "afw", - "bastionHosts": "bas", - "computeGallieries": "cg", - "dataCollectionEndpoints": "dce", - "dataCollectionRuleAssociations": "dcra", - "dataCollectionRules": "dcr", - "diagnosticSettings": "diag", - "diskAccesses": "da", - "diskEncryptionSets": "des", - "disks": "disk", - "firewallPolicies": "afwp", - "functionApps": "func", - "hostPools": "vdpool", - "ipConfigurations": "ipconf", - "keyVaults": "kv", - "logAnalyticsWorkspaces": "log", - "netAppAccounts": "naa", - "netAppCapacityPools": "nacp", - "networkInterfaces": "nic", - "networkSecurityGroups": "nsg", - "networkWatchers": "nw", - "privateEndpoints": "pe", - "privateLinkScopes": "pls", - "publicIPAddresses": "pip", - "recoveryServicesVaults": "rsv", - "remoteApplicationGroups": "vdag", - "resourceGroups": "rg", - "routeTables": "rt", - "scalingPlans": "vdscaling", - "storageAccounts": "st", - "subnets": "snet", - "userAssignedIdentities": "id", - "virtualMachines": "vm", - "virtualNetworks": "vnet", - "workspaces": "vdws" - }, - "locations": "[variables('$fxv#0')[environment().name]]", - "locationAbbreviation": "[variables('locations')[parameters('location')].abbreviation]", - "resourceAbbreviations": "[variables('$fxv#1')]", - "namingConvention": "[format('{0}-{1}{2}-{3}-{4}-{5}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", - "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", - "names": { - "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", - "applicationGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationGroups)]", - "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", - "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", - "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", - "automationAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", - "automationAccountNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", - "automationAccountPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", - "availabilitySet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').availabilitySets)]", - "azureFirewall": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').azureFirewalls)]", - "azureFirewallClientPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, format('client-{0}', variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallClientPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-client-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').azureFirewalls)]", - "azureFirewallManagementPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, format('mgmt-{0}', variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallManagementPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-mgmt-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').azureFirewalls))]", - "azureFirewallPolicy": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').firewallPolicies)]", - "bastionHost": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostNetworkSecurityGroup": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkSecurityGroups), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", - "bastionHostPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').bastionHosts))]", - "computeGallery": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').computeGallieries), '-', '_')]", - "dataCollectionEndpoint": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionEndpoints)]", - "dataCollectionRuleAssociation": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionRuleAssociations)]", - "dataCollectionRule": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionRules)]", - "diskAccess": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').diskAccesses)]", - "diskAccessNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').diskAccesses)]", - "diskAccessPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').diskAccesses)]", - "diskEncryptionSet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').diskEncryptionSets)]", - "functionApp": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').functionApps)]", - "functionAppNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').functionApps, parameters('tokens').service))]", - "functionAppPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').functionApps, parameters('tokens').service))]", - "hostPool": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').hostPools)]", - "hostPoolDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", - "hostPoolNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", - "hostPoolPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", - "keyVault": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').keyVaults), '-', ''), parameters('networkName'), parameters('networkShortName'))]", - "keyVaultDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", - "keyVaultNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", - "keyVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", - "logAnalyticsWorkspace": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').logAnalyticsWorkspaces)]", - "logAnalyticsWorkspaceDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').logAnalyticsWorkspaces)]", - "netAppAccountCapacityPool": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').netAppCapacityPools)]", - "netAppAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').netAppAccounts)]", - "networkSecurityGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').networkSecurityGroups)]", - "networkSecurityGroupDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').networkSecurityGroups)]", - "networkWatcher": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').networkWatchers)]", - "privateLinkScope": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').privateLinkScopes)]", - "privateLinkScopeNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').privateLinkScopes)]", - "privateLinkScopePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').privateLinkScopes)]", - "recoveryServicesVault": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').recoveryServicesVaults)]", - "recoveryServicesVaultNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", - "recoveryServicesVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", - "resourceGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').resourceGroups)]", - "routeTable": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').routeTables)]", - "scalingPlan": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').scalingPlans)]", - "scalingPlanDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').scalingPlans)]", - "storageAccount": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').storageAccounts), parameters('networkName'), parameters('networkShortName'))]", - "storageAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').storageAccounts))]", - "storageAccountBlobNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountFileNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-file', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountQueueNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-queue', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountTableNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-table', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountBlobPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountFilePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-file', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountQueuePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-queue', variables('resourceAbbreviations').storageAccounts))]", - "storageAccountTablePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-table', variables('resourceAbbreviations').storageAccounts))]", - "subnet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').subnets)]", - "userAssignedIdentity": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').userAssignedIdentities)]", - "virtualMachine": "[replace(replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').virtualMachines), parameters('environmentAbbreviation'), first(parameters('environmentAbbreviation'))), parameters('networkName'), ''), '-', '')]", - "virtualMachineDisk": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').disks), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", - "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", - "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", - "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", - "workspaceFeed": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobal": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" - } - }, - "resources": [], - "outputs": { - "locations": { - "type": "object", - "value": "[variables('locations')]" - }, - "names": { - "type": "object", - "value": "[variables('names')]" - }, - "resourceAbbreviations": { - "type": "object", - "value": "[variables('resourceAbbreviations')]" - }, - "tokens": { - "type": "object", - "value": "[parameters('tokens')]" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('private-dns-zones-{0}', parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "locations": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locations.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "2502930168536032010" - } - }, - "parameters": { - "locations": { - "type": "object" - } - }, - "variables": { - "copy": [ - { - "name": "privateDnsZoneNames_Backup", - "count": "[length(items(parameters('locations')))]", - "input": "[format('privatelink.{0}.backup.windowsazure.{1}', items(parameters('locations'))[copyIndex('privateDnsZoneNames_Backup')].value.recoveryServicesGeo, coalesce(variables('privateDnsZoneSuffixes_Backup')[environment().name], variables('cloudSuffix')))]" - } - ], - "cloudSuffix": "[replace(replace(environment().resourceManager, 'https://management.', ''), '/', '')]", - "privateDnsZoneNames": "[union(createArray(format('privatelink.agentsvc.azure-automation.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureAutomation')[environment().name], variables('cloudSuffix'))), format('privatelink.azure-automation.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureAutomation')[environment().name], variables('cloudSuffix'))), format('privatelink.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureWebSites')[environment().name], format('appservice.{0}', variables('cloudSuffix')))), format('scm.privatelink.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureWebSites')[environment().name], format('appservice.{0}', variables('cloudSuffix')))), format('privatelink.wvd.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureVirtualDesktop')[environment().name], variables('cloudSuffix'))), format('privatelink-global.wvd.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureVirtualDesktop')[environment().name], variables('cloudSuffix'))), format('privatelink.file.{0}', environment().suffixes.storage), format('privatelink.queue.{0}', environment().suffixes.storage), format('privatelink.table.{0}', environment().suffixes.storage), format('privatelink.blob.{0}', environment().suffixes.storage), format('privatelink{0}', replace(environment().suffixes.keyvaultDns, 'vault', 'vaultcore')), format('privatelink.monitor.{0}', coalesce(variables('privateDnsZoneSuffixes_Monitor')[environment().name], variables('cloudSuffix'))), format('privatelink.ods.opinsights.{0}', coalesce(variables('privateDnsZoneSuffixes_Monitor')[environment().name], variables('cloudSuffix'))), format('privatelink.oms.opinsights.{0}', coalesce(variables('privateDnsZoneSuffixes_Monitor')[environment().name], variables('cloudSuffix')))), variables('privateDnsZoneNames_Backup'))]", - "privateDnsZoneSuffixes_AzureAutomation": { - "AzureCloud": "net", - "AzureUSGovernment": "us", - "USNat": null, - "USSec": null - }, - "privateDnsZoneSuffixes_AzureVirtualDesktop": { - "AzureCloud": "microsoft.com", - "AzureUSGovernment": "azure.us", - "USNat": null, - "USSec": null - }, - "privateDnsZoneSuffixes_AzureWebSites": { - "AzureCloud": "azurewebsites.net", - "AzureUSGovernment": "azurewebsites.us", - "USNat": null, - "USSec": null - }, - "privateDnsZoneSuffixes_Backup": { - "AzureCloud": "com", - "AzureUSGovernment": "us", - "USNat": null, - "USSec": null - }, - "privateDnsZoneSuffixes_Monitor": { - "AzureCloud": "azure.com", - "AzureUSGovernment": "azure.us", - "USNat": null, - "USSec": null - } - }, - "resources": [], - "outputs": { - "names": { - "type": "array", - "value": "[variables('privateDnsZoneNames')]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix')))]" - ] - } - ], - "outputs": { - "locationProperties": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locations.value[parameters('location')]]" - }, - "mlzTags": { - "type": "object", - "value": "[variables('mlzTags')]" - }, - "privateDnsZones": { - "type": "array", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('private-dns-zones-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value]" - }, - "resourceAbbreviations": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" - }, - "tiers": { - "type": "array", - "copy": { - "count": "[length(parameters('networks'))]", - "input": { - "name": "[parameters('networks')[copyIndex()].name]", - "shortName": "[parameters('networks')[copyIndex()].shortName]", - "deployUniqueResources": "[parameters('networks')[copyIndex()].deployUniqueResources]", - "subscriptionId": "[parameters('networks')[copyIndex()].subscriptionId]", - "nsgDiagLogs": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'nsgDiagLogs'), createArray())]", - "nsgDiagMetrics": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'nsgDiagMetrics'), createArray())]", - "nsgRules": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'nsgRules'), createArray())]", - "vnetAddressPrefix": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'vnetAddressPrefix'), '')]", - "vnetDiagLogs": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'vnetDiagLogs'), createArray())]", - "vnetDiagMetrics": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'vnetDiagMetrics'), createArray())]", - "subnetAddressPrefix": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'subnetAddressPrefix'), '')]", - "namingConvention": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[copyIndex()].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value]" - } - } - }, - "tokens": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value]" - } - } - } - } - }, - { - "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "name": { - "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'network')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "17445726037807437290" - } - }, - "parameters": { - "mlzTags": { - "type": "object" - }, - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object", - "defaultValue": {} - } - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2019-05-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Resources/resourceGroups'), parameters('tags')['Microsoft.Resources/resourceGroups'], createObject()), parameters('mlzTags'))]" - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "location": { - "type": "string", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name')), '2019-05-01', 'full').location]" - }, - "tags": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name')), '2019-05-01', 'full').tags]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "additionalSubnets": { - "value": "[parameters('additionalSubnets')]" - }, - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "deployNetworkWatcher": { - "value": "[parameters('deployNetworkWatcher')]" - }, - "hubVirtualNetworkResourceId": { - "value": "[parameters('hubVirtualNetworkResourceId')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "networkSecurityGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.networkSecurityGroup]" - }, - "networkSecurityGroupRules": { - "value": "[parameters('networkSecurityGroupRules')]" - }, - "networkWatcherName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.networkWatcher]" - }, - "resourceGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "routeTableName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.routeTable]" - }, - "routeTableRouteNextHopIpAddress": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('firewallResourceId'), '/')[2], split(parameters('firewallResourceId'), '/')[4]), 'Microsoft.Network/azureFirewalls', split(parameters('firewallResourceId'), '/')[8]), '2020-11-01').ipConfigurations[0].properties.privateIPAddress]" - }, - "subnetAddressPrefix": { - "value": "[parameters('subnetAddressPrefix')]" - }, - "subnetName": "[if(empty(parameters('subnetName')), createObject('value', reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.subnet), createObject('value', parameters('subnetName')))]", - "subscriptionId": { - "value": "[variables('subscriptionId')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "virtualNetworkAddressPrefix": { - "value": "[parameters('virtualNetworkAddressPrefix')]" - }, - "virtualNetworkName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.virtualNetwork]" - }, - "vNetDnsServers": { - "value": "[coalesce(tryGet(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01'), 'dhcpOptions', 'dnsServers'), createArray())]" - }, - "workloadShortName": { - "value": "[parameters('workloadShortName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1068007055123133889" - } - }, - "parameters": { - "additionalSubnets": { - "type": "array" - }, - "deploymentNameSuffix": { - "type": "string" - }, - "deployNetworkWatcher": { - "type": "bool" - }, - "hubVirtualNetworkResourceId": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "networkSecurityGroupName": { - "type": "string" - }, - "networkSecurityGroupRules": { - "type": "array" - }, - "networkWatcherName": { - "type": "string" - }, - "resourceGroupName": { - "type": "string" - }, - "routeTableName": { - "type": "string" - }, - "routeTableRouteNextHopIpAddress": { - "type": "string" - }, - "subnetAddressPrefix": { - "type": "string" - }, - "subnetName": { - "type": "string" - }, - "subscriptionId": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "vNetDnsServers": { - "type": "array" - }, - "virtualNetworkAddressPrefix": { - "type": "string" - }, - "virtualNetworkName": { - "type": "string" - }, - "workloadShortName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "additionalSubnets": { - "value": "[parameters('additionalSubnets')]" - }, - "deployNetworkWatcher": { - "value": "[parameters('deployNetworkWatcher')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "networkSecurityGroupName": { - "value": "[parameters('networkSecurityGroupName')]" - }, - "networkSecurityGroupRules": { - "value": "[parameters('networkSecurityGroupRules')]" - }, - "networkWatcherName": { - "value": "[parameters('networkWatcherName')]" - }, - "resourceGroupName": { - "value": "[parameters('resourceGroupName')]" - }, - "routeTableName": { - "value": "[parameters('routeTableName')]" - }, - "routeTableRouteNextHopIpAddress": { - "value": "[parameters('routeTableRouteNextHopIpAddress')]" - }, - "subnetAddressPrefix": { - "value": "[parameters('subnetAddressPrefix')]" - }, - "subnetName": { - "value": "[parameters('subnetName')]" - }, - "subscriptionId": { - "value": "[parameters('subscriptionId')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "virtualNetworkAddressPrefix": { - "value": "[parameters('virtualNetworkAddressPrefix')]" - }, - "virtualNetworkName": { - "value": "[parameters('virtualNetworkName')]" - }, - "vNetDnsServers": { - "value": "[parameters('vNetDnsServers')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "11567108053836979012" - } - }, - "parameters": { - "additionalSubnets": { - "type": "array", - "defaultValue": [] - }, - "deployNetworkWatcher": { - "type": "bool" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "networkSecurityGroupName": { - "type": "string" - }, - "networkSecurityGroupRules": { - "type": "array" - }, - "networkWatcherName": { - "type": "string" - }, - "resourceGroupName": { - "type": "string" - }, - "routeTableName": { - "type": "string" - }, - "routeTableRouteNextHopIpAddress": { - "type": "string" - }, - "subnetAddressPrefix": { - "type": "string" - }, - "subnetName": { - "type": "string" - }, - "subscriptionId": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "virtualNetworkAddressPrefix": { - "type": "string" - }, - "virtualNetworkName": { - "type": "string" - }, - "vNetDnsServers": { - "type": "array" - } - }, - "variables": { - "delegations": { - "AzureNetAppFiles": [ - { - "name": "Microsoft.Netapp.volumes", - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets/delegations', parameters('virtualNetworkName'), 'AzureNetAppFiles', 'delegation')]", - "properties": { - "serviceName": "Microsoft.Netapp/volumes" - }, - "type": "Microsoft.Network/virtualNetworks/subnets/delegations" - } - ], - "FunctionAppOutbound": [ - { - "name": "Microsoft.Web/sites", - "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets/delegations', parameters('virtualNetworkName'), 'FunctionAppOutbound', 'delegation')]", - "properties": { - "serviceName": "Microsoft.Web/serverfarms" - }, - "type": "Microsoft.Network/virtualNetworks/subnets/delegations" - } - ] - }, - "subnets": "[union(createArray(createObject('name', parameters('subnetName'), 'properties', createObject('addressPrefix', parameters('subnetAddressPrefix')))), parameters('additionalSubnets'))]" - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "networkSecurityGroup", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "name": { - "value": "[parameters('networkSecurityGroupName')]" - }, - "securityRules": { - "value": "[parameters('networkSecurityGroupRules')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "2196017082128829477" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "name": { - "type": "string" - }, - "securityRules": { - "type": "array" - }, - "tags": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Network/networkSecurityGroups", - "apiVersion": "2021-02-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/networkSecurityGroups'), parameters('tags')['Microsoft.Network/networkSecurityGroups'], createObject()), parameters('mlzTags'))]", - "properties": { - "securityRules": "[parameters('securityRules')]" - } - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "routeTable", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "disableBgpRoutePropagation": { - "value": true - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "name": { - "value": "[parameters('routeTableName')]" - }, - "routeNextHopIpAddress": { - "value": "[parameters('routeTableRouteNextHopIpAddress')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "8417416771003518918" - } - }, - "parameters": { - "disableBgpRoutePropagation": { - "type": "bool" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "name": { - "type": "string" - }, - "routeAddressPrefix": { - "type": "string", - "defaultValue": "0.0.0.0/0" - }, - "routeName": { - "type": "string", - "defaultValue": "default_route" - }, - "routeNextHopIpAddress": { - "type": "string" - }, - "routeNextHopType": { - "type": "string", - "defaultValue": "VirtualAppliance" - }, - "tags": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Network/routeTables", - "apiVersion": "2021-02-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/routeTables'), parameters('tags')['Microsoft.Network/routeTables'], createObject()), parameters('mlzTags'))]", - "properties": { - "disableBgpRoutePropagation": "[parameters('disableBgpRoutePropagation')]", - "routes": [ - { - "name": "[parameters('routeName')]", - "properties": { - "addressPrefix": "[parameters('routeAddressPrefix')]", - "nextHopIpAddress": "[parameters('routeNextHopIpAddress')]", - "nextHopType": "[parameters('routeNextHopType')]" - } - } - ] - } - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Network/routeTables', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - } - } - } - } - }, - { - "condition": "[parameters('deployNetworkWatcher')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "networkWatcher", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "name": { - "value": "[parameters('networkWatcherName')]" - }, - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "4071285799602638747" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "name": { - "type": "string" - }, - "tags": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Network/networkWatchers", - "apiVersion": "2021-02-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/networkWatchers'), parameters('tags')['Microsoft.Network/networkWatchers'], createObject()), parameters('mlzTags'))]", - "properties": {} - } - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "virtualNetwork", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "addressPrefix": { - "value": "[parameters('virtualNetworkAddressPrefix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "name": { - "value": "[parameters('virtualNetworkName')]" - }, - "subnets": { - "copy": [ - { - "name": "value", - "count": "[length(variables('subnets'))]", - "input": "[createObject('name', variables('subnets')[copyIndex('value')].name, 'properties', createObject('addressPrefix', variables('subnets')[copyIndex('value')].properties.addressPrefix, 'delegations', coalesce(tryGet(variables('delegations'), variables('subnets')[copyIndex('value')].name), createArray()), 'networkSecurityGroup', createObject('id', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup'), '2022-09-01').outputs.id.value), 'routeTable', createObject('id', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'routeTable'), '2022-09-01').outputs.id.value), 'privateEndpointNetworkPolicies', 'Disabled', 'privateLinkServiceNetworkPolicies', 'Disabled'))]" - } - ] - }, - "tags": { - "value": "[parameters('tags')]" - }, - "vNetDnsServers": { - "value": "[parameters('vNetDnsServers')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "3465065949976146403" - } - }, - "parameters": { - "addressPrefix": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "name": { - "type": "string" - }, - "subnets": { - "type": "array" - }, - "tags": { - "type": "object" - }, - "vNetDnsServers": { - "type": "array" - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks", - "apiVersion": "2021-02-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/virtualNetworks'), parameters('tags')['Microsoft.Network/virtualNetworks'], createObject()), parameters('mlzTags'))]", - "properties": { - "addressSpace": { - "addressPrefixes": [ - "[parameters('addressPrefix')]" - ] - }, - "subnets": "[parameters('subnets')]", - "dhcpOptions": "[if(empty(parameters('vNetDnsServers')), null(), createObject('dnsServers', parameters('vNetDnsServers')))]" - } - } - ], - "outputs": { - "addressPrefix": { - "type": "string", - "value": "[reference(resourceId('Microsoft.Network/virtualNetworks', parameters('name')), '2021-02-01').addressSpace.addressPrefixes[0]]" - }, - "dnsServers": { - "type": "array", - "value": "[parameters('vNetDnsServers')]" - }, - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "subnets": { - "type": "array", - "value": "[reference(resourceId('Microsoft.Network/virtualNetworks', parameters('name')), '2021-02-01').subnets]" - } - } - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup')]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkWatcher')]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'routeTable')]" - ] - } - ], - "outputs": { - "networkSecurityGroupName": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup'), '2022-09-01').outputs.name.value]" - }, - "networkSecurityGroupResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup'), '2022-09-01').outputs.id.value]" - }, - "subnets": { - "type": "array", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.subnets.value]" - }, - "virtualNetworkAddressPrefix": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.addressPrefix.value]" - }, - "virtualNetworkName": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.name.value]" - }, - "virtualNetworkResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.id.value]" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-spoke-peering-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "hubVirtualNetworkResourceId": { - "value": "[parameters('hubVirtualNetworkResourceId')]" - }, - "resourceGroupName": { - "value": "[parameters('resourceGroupName')]" - }, - "spokeShortName": { - "value": "[parameters('workloadShortName')]" - }, - "spokeVirtualNetworkName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" - }, - "subscriptionId": { - "value": "[parameters('subscriptionId')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "15799890372401066181" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "hubVirtualNetworkResourceId": { - "type": "string" - }, - "resourceGroupName": { - "type": "string" - }, - "spokeShortName": { - "type": "string" - }, - "spokeVirtualNetworkName": { - "type": "string" - }, - "subscriptionId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('peer-{0}-to-hub-{1}', parameters('spokeShortName'), parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "remoteVirtualNetworkResourceId": { - "value": "[parameters('hubVirtualNetworkResourceId')]" - }, - "virtualNetworkName": { - "value": "[parameters('spokeVirtualNetworkName')]" - }, - "virtualNetworkPeerName": { - "value": "[format('to-{0}', split(parameters('hubVirtualNetworkResourceId'), '/')[8])]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5031620623183573702" - } - }, - "parameters": { - "remoteVirtualNetworkResourceId": { - "type": "string" - }, - "virtualNetworkName": { - "type": "string" - }, - "virtualNetworkPeerName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", - "apiVersion": "2021-02-01", - "name": "[format('{0}/{1}', parameters('virtualNetworkName'), parameters('virtualNetworkPeerName'))]", - "properties": { - "allowForwardedTraffic": true, - "remoteVirtualNetwork": { - "id": "[parameters('remoteVirtualNetworkResourceId')]" - } - } - } - ] - } - } - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-hub-peering-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "hubVirtualNetworkName": { - "value": "[split(parameters('hubVirtualNetworkResourceId'), '/')[8]]" - }, - "resourceGroupName": { - "value": "[split(parameters('hubVirtualNetworkResourceId'), '/')[4]]" - }, - "spokeShortName": { - "value": "[parameters('workloadShortName')]" - }, - "spokeVirtualNetworkResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkResourceId.value]" - }, - "subscriptionId": { - "value": "[split(parameters('hubVirtualNetworkResourceId'), '/')[2]]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6489616383757058493" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "hubVirtualNetworkName": { - "type": "string" - }, - "resourceGroupName": { - "type": "string" - }, - "spokeShortName": { - "type": "string" - }, - "spokeVirtualNetworkResourceId": { - "type": "string" - }, - "subscriptionId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('peer-hub-to-{0}-{1}', parameters('spokeShortName'), parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('subscriptionId')]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "remoteVirtualNetworkResourceId": { - "value": "[parameters('spokeVirtualNetworkResourceId')]" - }, - "virtualNetworkName": { - "value": "[parameters('hubVirtualNetworkName')]" - }, - "virtualNetworkPeerName": { - "value": "[format('to-{0}', split(parameters('spokeVirtualNetworkResourceId'), '/')[8])]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5031620623183573702" - } - }, - "parameters": { - "remoteVirtualNetworkResourceId": { - "type": "string" - }, - "virtualNetworkName": { - "type": "string" - }, - "virtualNetworkPeerName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", - "apiVersion": "2021-02-01", - "name": "[format('{0}/{1}', parameters('virtualNetworkName'), parameters('virtualNetworkPeerName'))]", - "properties": { - "allowForwardedTraffic": true, - "remoteVirtualNetwork": { - "id": "[parameters('remoteVirtualNetworkResourceId')]" - } - } - } - ] - } - } - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - } - ], - "outputs": { - "networkSecurityGroupName": { - "type": "string", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.networkSecurityGroupName.value]" - }, - "subnets": { - "type": "array", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value]" - }, - "virtualNetworkName": { - "type": "string", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-vnet-links-{0}-sub-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "resourceGroup": "[variables('hubResourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "azureFirewallSku": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('firewallResourceId'), '/')[2], split(parameters('firewallResourceId'), '/')[4]), 'Microsoft.Network/azureFirewalls', split(parameters('firewallResourceId'), '/')[8]), '2020-11-01').sku.tier]" - }, - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "privateDnsZoneNames": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value]" - }, - "virtualNetworkName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" - }, - "virtualNetworkResourceGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "virtualNetworkSubscriptionId": { - "value": "[variables('subscriptionId')]" - }, - "workloadShortName": { - "value": "[parameters('workloadShortName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "7410232214960945771" - } - }, - "parameters": { - "azureFirewallSku": { - "type": "string" - }, - "deploymentNameSuffix": { - "type": "string" - }, - "privateDnsZoneNames": { - "type": "array" - }, - "virtualNetworkName": { - "type": "string" - }, - "virtualNetworkResourceGroupName": { - "type": "string" - }, - "virtualNetworkSubscriptionId": { - "type": "string" - }, - "workloadShortName": { - "type": "string" - } - }, - "resources": [ - { - "condition": "[equals(parameters('azureFirewallSku'), 'Basic')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-vnet-links-{0}-rg-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "privateDnsZoneNames": { - "value": "[parameters('privateDnsZoneNames')]" - }, - "virtualNetworkName": { - "value": "[parameters('virtualNetworkName')]" - }, - "virtualNetworkResourceGroupName": { - "value": "[parameters('virtualNetworkResourceGroupName')]" - }, - "virtualNetworkSubscriptionId": { - "value": "[parameters('virtualNetworkSubscriptionId')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "12405780209119797551" - } - }, - "parameters": { - "privateDnsZoneNames": { - "type": "array" - }, - "virtualNetworkName": { - "type": "string" - }, - "virtualNetworkResourceGroupName": { - "type": "string" - }, - "virtualNetworkSubscriptionId": { - "type": "string" - } - }, - "resources": [ - { - "copy": { - "name": "virtualNetworkLinks", - "count": "[length(parameters('privateDnsZoneNames'))]" - }, - "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", - "apiVersion": "2018-09-01", - "name": "[format('{0}/{1}', parameters('privateDnsZoneNames')[copyIndex()], parameters('virtualNetworkName'))]", - "location": "global", - "properties": { - "registrationEnabled": false, - "virtualNetwork": { - "id": "[resourceId(parameters('virtualNetworkSubscriptionId'), parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]" - } - } - } - ] - } - } - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" - }, - "keyVaultPrivateDnsZoneResourceId": { - "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', replace(format('privatelink{0}', environment().suffixes.keyvaultDns), 'vault', 'vaultcore'))]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "resourceAbbreviations": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" - }, - "resourceGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "subnetResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[0].id]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "tier": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" - }, - "tokens": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value]" - }, - "workloadShortName": { - "value": "[parameters('workloadShortName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6386888682917235118" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "environmentAbbreviation": { - "type": "string" - }, - "keyVaultPrivateDnsZoneResourceId": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "resourceAbbreviations": { - "type": "object" - }, - "resourceGroupName": { - "type": "string" - }, - "subnetResourceId": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "tier": { - "type": "object" - }, - "tokens": { - "type": "object" - }, - "workloadShortName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" - }, - "keyVaultPrivateDnsZoneResourceId": { - "value": "[parameters('keyVaultPrivateDnsZoneResourceId')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "resourceAbbreviations": { - "value": "[parameters('resourceAbbreviations')]" - }, - "subnetResourceId": { - "value": "[parameters('subnetResourceId')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "tier": { - "value": "[parameters('tier')]" - }, - "tokens": { - "value": "[parameters('tokens')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "419730844167715947" - } - }, - "parameters": { - "diskEncryptionKeyExpirationInDays": { - "type": "int", - "defaultValue": 30 - }, - "environmentAbbreviation": { - "type": "string" - }, - "keyVaultPrivateDnsZoneResourceId": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "resourceAbbreviations": { - "type": "object" - }, - "subnetResourceId": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "tier": { - "type": "object" - }, - "tokens": { - "type": "object" - } - }, - "variables": { - "keyVaultPrivateEndpointName": "[replace(parameters('tier').namingConvention.keyVaultPrivateEndpoint, parameters('tokens').service, 'cmk')]" - }, - "resources": [ - { - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2022-07-01", - "name": "[format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id))]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.KeyVault/vaults'), parameters('tags')['Microsoft.KeyVault/vaults'], createObject()), parameters('mlzTags'))]", - "properties": { - "enabledForDeployment": false, - "enabledForDiskEncryption": false, - "enabledForTemplateDeployment": false, - "enablePurgeProtection": true, - "enableRbacAuthorization": true, - "enableSoftDelete": true, - "networkAcls": { - "bypass": "AzureServices", - "defaultAction": "Deny", - "ipRules": [], - "virtualNetworkRules": [] - }, - "publicNetworkAccess": "Disabled", - "sku": { - "family": "A", - "name": "premium" - }, - "softDeleteRetentionInDays": "[if(or(equals(parameters('environmentAbbreviation'), 'dev'), equals(parameters('environmentAbbreviation'), 'test')), 7, 90)]", - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[variables('keyVaultPrivateEndpointName')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", - "properties": { - "customNetworkInterfaceName": "[replace(parameters('tier').namingConvention.keyVaultNetworkInterface, parameters('tokens').service, 'cmk')]", - "privateLinkServiceConnections": [ - { - "name": "[variables('keyVaultPrivateEndpointName')]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]", - "groupIds": [ - "vault" - ] - } - } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" - ] - }, - { - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2021-08-01", - "name": "[format('{0}/{1}', variables('keyVaultPrivateEndpointName'), format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]", - "properties": { - "privateDnsZoneConfigs": [ - { - "name": "ipconfig1", - "properties": { - "privateDnsZoneId": "[parameters('keyVaultPrivateDnsZoneResourceId')]" - } - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', variables('keyVaultPrivateEndpointName'))]", - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" - ] - }, - { - "type": "Microsoft.KeyVault/vaults/keys", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)), 'DiskEncryptionKey')]", - "properties": { - "attributes": { - "enabled": true - }, - "keySize": 4096, - "kty": "RSA", - "rotationPolicy": { - "attributes": { - "expiryTime": "[format('P{0}D', string(parameters('diskEncryptionKeyExpirationInDays')))]" - }, - "lifetimeActions": [ - { - "action": { - "type": "Notify" - }, - "trigger": { - "timeBeforeExpiry": "P10D" - } - }, - { - "action": { - "type": "Rotate" - }, - "trigger": { - "timeAfterCreate": "[format('P{0}D', string(sub(parameters('diskEncryptionKeyExpirationInDays'), 7)))]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" - ] - }, - { - "type": "Microsoft.KeyVault/vaults/keys", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)), 'StorageEncryptionKey')]", - "properties": { - "attributes": { - "enabled": true - }, - "keySize": 4096, - "kty": "RSA", - "rotationPolicy": { - "attributes": { - "expiryTime": "[format('P{0}D', string(parameters('diskEncryptionKeyExpirationInDays')))]" - }, - "lifetimeActions": [ - { - "action": { - "type": "Notify" - }, - "trigger": { - "timeBeforeExpiry": "P10D" - } - }, - { - "action": { - "type": "Rotate" - }, - "trigger": { - "timeAfterCreate": "[format('P{0}D', string(sub(parameters('diskEncryptionKeyExpirationInDays'), 7)))]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" - ] - } - ], - "outputs": { - "keyUriWithVersion": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults/keys', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)), 'DiskEncryptionKey'), '2022-07-01').keyUriWithVersion]" - }, - "keyVaultResourceId": { - "type": "string", - "value": "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" - }, - "keyVaultName": { - "type": "string", - "value": "[format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id))]" - }, - "keyVaultUri": { - "type": "string", - "value": "[reference(resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id))), '2022-07-01').vaultUri]" - }, - "storageKeyName": { - "type": "string", - "value": "StorageEncryptionKey" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-des-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "diskEncryptionSetName": { - "value": "[parameters('tier').namingConvention.diskEncryptionSet]" - }, - "keyUrl": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyUriWithVersion.value]" - }, - "keyVaultResourceId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultResourceId.value]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "tags": "[if(contains(parameters('tags'), 'Microsoft.Compute/diskEncryptionSets'), createObject('value', parameters('tags')['Microsoft.Compute/diskEncryptionSets']), createObject('value', createObject()))]", - "workloadShortName": { - "value": "[parameters('workloadShortName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "7946295394028911325" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "diskEncryptionSetName": { - "type": "string" - }, - "keyUrl": { - "type": "string" - }, - "keyVaultResourceId": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "tags": { - "type": "object" - }, - "workloadShortName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Compute/diskEncryptionSets", - "apiVersion": "2023-04-02", - "name": "[parameters('diskEncryptionSetName')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Compute/diskEncryptionSets'), parameters('tags')['Microsoft.Compute/diskEncryptionSets'], createObject()), parameters('mlzTags'))]", - "identity": { - "type": "SystemAssigned" - }, - "properties": { - "activeKey": { - "sourceVault": { - "id": "[parameters('keyVaultResourceId')]" - }, - "keyUrl": "[parameters('keyUrl')]" - }, - "encryptionType": "EncryptionAtRestWithPlatformAndCustomerKeys", - "rotationToLatestKeyVersionEnabled": true - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('assign-role-des-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "principalId": { - "value": "[reference(resourceId('Microsoft.Compute/diskEncryptionSets', parameters('diskEncryptionSetName')), '2023-04-02', 'full').identity.principalId]" - }, - "principalType": { - "value": "ServicePrincipal" - }, - "roleDefinitionId": { - "value": "[resourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]" - }, - "targetResourceId": { - "value": "[resourceGroup().id]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "967013811257719495" - } - }, - "parameters": { - "targetResourceId": { - "type": "string" - }, - "roleDefinitionId": { - "type": "string" - }, - "principalId": { - "type": "string" - }, - "principalType": { - "type": "string", - "defaultValue": "ServicePrincipal", - "allowedValues": [ - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ] - }, - "description": { - "type": "string", - "defaultValue": "" - } - }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(parameters('targetResourceId'), parameters('roleDefinitionId'), parameters('principalId'))]", - "properties": { - "principalId": "[parameters('principalId')]", - "principalType": "[parameters('principalType')]", - "roleDefinitionId": "[parameters('roleDefinitionId')]", - "description": "[parameters('description')]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/diskEncryptionSets', parameters('diskEncryptionSetName'))]" - ] - } - ], - "outputs": { - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.Compute/diskEncryptionSets', parameters('diskEncryptionSetName'))]" - } - } - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-id-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultName": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultName.value]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "userAssignedIdentityName": { - "value": "[replace(parameters('tier').namingConvention.userAssignedIdentity, format('-{0}', parameters('tokens').service), '')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "9115514582672423063" - } - }, - "parameters": { - "keyVaultName": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "tags": { - "type": "object" - }, - "userAssignedIdentityName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[parameters('userAssignedIdentityName')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.ManagedIdentity/userAssignedIdentities'), parameters('tags')['Microsoft.ManagedIdentity/userAssignedIdentities'], createObject()), parameters('mlzTags'))]" - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('keyVaultName'))]", - "name": "[guid(parameters('userAssignedIdentityName'), 'e147488a-f6f5-4113-8e2d-b22465e65bf6', parameters('keyVaultName'))]", - "properties": { - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName')), '2018-11-30').principalId]", - "principalType": "ServicePrincipal", - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]" - ] - } - ], - "outputs": { - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]" - } - } - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - } - ], - "outputs": { - "diskEncryptionSetResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-des-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - }, - "keyVaultName": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultName.value]" - }, - "keyVaultUri": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value]" - }, - "keyVaultResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultResourceId.value]" - }, - "storageKeyName": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageKeyName.value]" - }, - "userAssignedIdentityResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "blobsPrivateDnsZoneResourceId": { - "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.blob.{0}', environment().suffixes.storage))]" - }, - "filesPrivateDnsZoneResourceId": { - "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.file.{0}', environment().suffixes.storage))]" - }, - "keyVaultUri": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value]" - }, - "location": { - "value": "[parameters('location')]" - }, - "logStorageSkuName": { - "value": "[parameters('logStorageSkuName')]" - }, - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "network": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" - }, - "queuesPrivateDnsZoneResourceId": { - "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.queue.{0}', environment().suffixes.storage))]" - }, - "resourceGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "serviceToken": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" - }, - "storageEncryptionKeyName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageKeyName.value]" - }, - "subnetResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[0].id]" - }, - "tablesPrivateDnsZoneResourceId": { - "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.table.{0}', environment().suffixes.storage))]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "tier": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" - }, - "userAssignedIdentityResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.userAssignedIdentityResourceId.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "11229301381209629588" - } - }, - "parameters": { - "blobsPrivateDnsZoneResourceId": { - "type": "string" - }, - "filesPrivateDnsZoneResourceId": { - "type": "string" - }, - "keyVaultUri": { - "type": "string" - }, - "logStorageSkuName": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "network": { - "type": "object" - }, - "queuesPrivateDnsZoneResourceId": { - "type": "string" - }, - "resourceGroupName": { - "type": "string" - }, - "serviceToken": { - "type": "string" - }, - "storageEncryptionKeyName": { - "type": "string" - }, - "subnetResourceId": { - "type": "string" - }, - "tablesPrivateDnsZoneResourceId": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "tier": { - "type": "object" - }, - "userAssignedIdentityResourceId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "storage", - "subscriptionId": "[parameters('network').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "blobsPrivateDnsZoneResourceId": { - "value": "[parameters('blobsPrivateDnsZoneResourceId')]" - }, - "filesPrivateDnsZoneResourceId": { - "value": "[parameters('filesPrivateDnsZoneResourceId')]" - }, - "keyVaultUri": { - "value": "[parameters('keyVaultUri')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "queuesPrivateDnsZoneResourceId": { - "value": "[parameters('queuesPrivateDnsZoneResourceId')]" - }, - "serviceToken": { - "value": "[parameters('serviceToken')]" - }, - "skuName": { - "value": "[parameters('logStorageSkuName')]" - }, - "storageEncryptionKeyName": { - "value": "[parameters('storageEncryptionKeyName')]" - }, - "subnetResourceId": { - "value": "[parameters('subnetResourceId')]" - }, - "tablesPrivateDnsZoneResourceId": { - "value": "[parameters('tablesPrivateDnsZoneResourceId')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "tier": { - "value": "[parameters('tier')]" - }, - "userAssignedIdentityResourceId": { - "value": "[parameters('userAssignedIdentityResourceId')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "10245709494871874056" - } - }, - "parameters": { - "blobsPrivateDnsZoneResourceId": { - "type": "string" - }, - "filesPrivateDnsZoneResourceId": { - "type": "string" - }, - "keyVaultUri": { - "type": "string" - }, - "location": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "queuesPrivateDnsZoneResourceId": { - "type": "string" - }, - "serviceToken": { - "type": "string" - }, - "skuName": { - "type": "string" - }, - "storageEncryptionKeyName": { - "type": "string" - }, - "subnetResourceId": { - "type": "string" - }, - "tablesPrivateDnsZoneResourceId": { - "type": "string" - }, - "tags": { - "type": "object" - }, - "tier": { - "type": "object" - }, - "userAssignedIdentityResourceId": { - "type": "string" - } - }, - "variables": { - "subResources": [ - { - "id": "[parameters('blobsPrivateDnsZoneResourceId')]", - "nic": "[parameters('tier').namingConvention.storageAccountBlobNetworkInterface]", - "pe": "[parameters('tier').namingConvention.storageAccountBlobPrivateEndpoint]" - }, - { - "id": "[parameters('filesPrivateDnsZoneResourceId')]", - "nic": "[parameters('tier').namingConvention.storageAccountFileNetworkInterface]", - "pe": "[parameters('tier').namingConvention.storageAccountFilePrivateEndpoint]" - }, - { - "id": "[parameters('queuesPrivateDnsZoneResourceId')]", - "nic": "[parameters('tier').namingConvention.storageAccountQueueNetworkInterface]", - "pe": "[parameters('tier').namingConvention.storageAccountQueuePrivateEndpoint]" - }, - { - "id": "[parameters('tablesPrivateDnsZoneResourceId')]", - "nic": "[parameters('tier').namingConvention.storageAccountTableNetworkInterface]", - "pe": "[parameters('tier').namingConvention.storageAccountTablePrivateEndpoint]" - } - ] - }, - "resources": [ - { - "type": "Microsoft.Storage/storageAccounts", - "apiVersion": "2023-01-01", - "name": "[uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id)]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Storage/storageAccounts'), parameters('tags')['Microsoft.Storage/storageAccounts'], createObject()), parameters('mlzTags'))]", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', parameters('userAssignedIdentityResourceId'))]": {} - } - }, - "kind": "StorageV2", - "sku": { - "name": "[parameters('skuName')]" - }, - "properties": { - "accessTier": "Hot", - "allowBlobPublicAccess": false, - "allowCrossTenantReplication": false, - "allowedCopyScope": "PrivateLink", - "allowSharedKeyAccess": false, - "defaultToOAuthAuthentication": false, - "dnsEndpointType": "Standard", - "encryption": { - "identity": { - "userAssignedIdentity": "[parameters('userAssignedIdentityResourceId')]" - }, - "keySource": "Microsoft.KeyVault", - "keyvaultproperties": { - "keyvaulturi": "[parameters('keyVaultUri')]", - "keyname": "[parameters('storageEncryptionKeyName')]" - }, - "requireInfrastructureEncryption": true, - "services": { - "blob": { - "keyType": "Account", - "enabled": true - }, - "file": { - "keyType": "Account", - "enabled": true - }, - "queue": { - "keyType": "Account", - "enabled": true - }, - "table": { - "keyType": "Account", - "enabled": true - } - } - }, - "minimumTlsVersion": "TLS1_2", - "networkAcls": { - "bypass": "AzureServices", - "virtualNetworkRules": [], - "ipRules": [], - "defaultAction": "Deny" - }, - "publicNetworkAccess": "Disabled", - "supportsHttpsTrafficOnly": true - } - }, - { - "copy": { - "name": "privateEndpoints", - "count": "[length(variables('subResources'))]" - }, - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[variables('subResources')[copyIndex()].pe]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", - "properties": { - "customNetworkInterfaceName": "[variables('subResources')[copyIndex()].nic]", - "privateLinkServiceConnections": [ - { - "name": "[variables('subResources')[copyIndex()].pe]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]", - "groupIds": [ - "[split(split(variables('subResources')[copyIndex()].id, '/')[8], '.')[1]]" - ] - } - } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]" - ] - }, - { - "copy": { - "name": "privateDnsZoneGroups", - "count": "[length(variables('subResources'))]" - }, - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2021-08-01", - "name": "[format('{0}/{1}', variables('subResources')[copyIndex()].pe, uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]", - "properties": { - "privateDnsZoneConfigs": [ - { - "name": "ipconfig1", - "properties": { - "privateDnsZoneId": "[variables('subResources')[copyIndex()].id]" - } - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', variables('subResources')[copyIndex()].pe)]", - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]" - ] - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]" - } - } - } - } - } - ], - "outputs": { - "storageAccountResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('network').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'storage'), '2022-09-01').outputs.id.value]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-diag-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deployActivityLogDiagnosticSetting": { - "value": "[parameters('deployActivityLogDiagnosticSetting')]" - }, - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "keyVaultDiagnosticLogs": { - "value": "[parameters('keyVaultDiagnosticsLogs')]" - }, - "keyVaultName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultName.value]" - }, - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "networkSecurityGroupDiagnosticsLogs": { - "value": "[parameters('networkSecurityGroupDiagnosticsLogs')]" - }, - "networkSecurityGroupDiagnosticsMetrics": { - "value": "[parameters('networkSecurityGroupDiagnosticsMetrics')]" - }, - "networkSecurityGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.networkSecurityGroupName.value]" - }, - "resourceGroupName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "serviceToken": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" - }, - "storageAccountResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageAccountResourceId.value]" - }, - "tier": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" - }, - "virtualNetworkDiagnosticsLogs": { - "value": "[parameters('virtualNetworkDiagnosticsLogs')]" - }, - "virtualNetworkDiagnosticsMetrics": { - "value": "[parameters('virtualNetworkDiagnosticsMetrics')]" - }, - "virtualNetworkName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "13756267312445220554" - } - }, - "parameters": { - "deployActivityLogDiagnosticSetting": { - "type": "bool" - }, - "deploymentNameSuffix": { - "type": "string" - }, - "keyVaultDiagnosticLogs": { - "type": "array" - }, - "keyVaultName": { - "type": "string" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "networkSecurityGroupDiagnosticsLogs": { - "type": "array" - }, - "networkSecurityGroupDiagnosticsMetrics": { - "type": "array" - }, - "networkSecurityGroupName": { - "type": "string" - }, - "resourceGroupName": { - "type": "string" - }, - "serviceToken": { - "type": "string" - }, - "storageAccountResourceId": { - "type": "string" - }, - "tier": { - "type": "object" - }, - "virtualNetworkDiagnosticsLogs": { - "type": "array" - }, - "virtualNetworkDiagnosticsMetrics": { - "type": "array" - }, - "virtualNetworkName": { - "type": "string" - } - }, - "resources": [ - { - "condition": "[parameters('deployActivityLogDiagnosticSetting')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-activity-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "logAnalyticsWorkspaceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5964906331561259426" - } - }, - "parameters": { - "logAnalyticsWorkspaceId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2017-05-01-preview", - "name": "[format('diag-activity-log-{0}', subscription().subscriptionId)]", - "properties": { - "workspaceId": "[parameters('logAnalyticsWorkspaceId')]", - "logs": [ - { - "category": "Administrative", - "enabled": true - }, - { - "category": "Security", - "enabled": true - }, - { - "category": "ServiceHealth", - "enabled": true - }, - { - "category": "Alert", - "enabled": true - }, - { - "category": "Recommendation", - "enabled": true - }, - { - "category": "Policy", - "enabled": true - }, - { - "category": "Autoscale", - "enabled": true - }, - { - "category": "ResourceHealth", - "enabled": true - } - ] - } - } - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-kv-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "keyVaultDiagnosticSettingName": { - "value": "[replace(parameters('tier').namingConvention.keyVaultDiagnosticSetting, format('{0}-', parameters('serviceToken')), '')]" - }, - "keyVaultName": { - "value": "[parameters('keyVaultName')]" - }, - "keyVaultStorageAccountId": { - "value": "[parameters('storageAccountResourceId')]" - }, - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "logs": { - "value": "[parameters('keyVaultDiagnosticLogs')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "13721817451936402949" - } - }, - "parameters": { - "keyVaultDiagnosticSettingName": { - "type": "string" - }, - "keyVaultName": { - "type": "string" - }, - "keyVaultStorageAccountId": { - "type": "string" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "logs": { - "type": "array" - } - }, - "resources": [ - { - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2017-05-01-preview", - "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('keyVaultName'))]", - "name": "[parameters('keyVaultDiagnosticSettingName')]", - "properties": { - "storageAccountId": "[parameters('keyVaultStorageAccountId')]", - "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]", - "logs": "[parameters('logs')]" - } - } - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-nsg-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "logs": { - "value": "[parameters('networkSecurityGroupDiagnosticsLogs')]" - }, - "logStorageAccountResourceId": { - "value": "[parameters('storageAccountResourceId')]" - }, - "metrics": { - "value": "[parameters('networkSecurityGroupDiagnosticsMetrics')]" - }, - "networkSecurityGroupDiagnosticSettingName": { - "value": "[parameters('tier').namingConvention.networkSecurityGroupDiagnosticSetting]" - }, - "networkSecurityGroupName": { - "value": "[parameters('networkSecurityGroupName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5533529544253509904" - } - }, - "parameters": { - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "logs": { - "type": "array" - }, - "logStorageAccountResourceId": { - "type": "string" - }, - "metrics": { - "type": "array" - }, - "networkSecurityGroupDiagnosticSettingName": { - "type": "string" - }, - "networkSecurityGroupName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2017-05-01-preview", - "scope": "[format('Microsoft.Network/networkSecurityGroups/{0}', parameters('networkSecurityGroupName'))]", - "name": "[parameters('networkSecurityGroupDiagnosticSettingName')]", - "properties": { - "storageAccountId": "[parameters('logStorageAccountResourceId')]", - "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]", - "logs": "[parameters('logs')]", - "metrics": "[parameters('metrics')]" - } - } - ] - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-vnet-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tier').subscriptionId]", - "resourceGroup": "[parameters('resourceGroupName')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "logs": { - "value": "[parameters('virtualNetworkDiagnosticsLogs')]" - }, - "logStorageAccountResourceId": { - "value": "[parameters('storageAccountResourceId')]" - }, - "metrics": { - "value": "[parameters('virtualNetworkDiagnosticsMetrics')]" - }, - "virtualNetworkDiagnosticSettingName": { - "value": "[parameters('tier').namingConvention.virtualNetworkDiagnosticSetting]" - }, - "virtualNetworkName": { - "value": "[parameters('virtualNetworkName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "169088610601729285" - } - }, - "parameters": { - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "logs": { - "type": "array" - }, - "logStorageAccountResourceId": { - "type": "string" - }, - "metrics": { - "type": "array" - }, - "virtualNetworkDiagnosticSettingName": { - "type": "string" - }, - "virtualNetworkName": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2017-05-01-preview", - "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('virtualNetworkName'))]", - "name": "[parameters('virtualNetworkDiagnosticSettingName')]", - "properties": { - "storageAccountId": "[parameters('logStorageAccountResourceId')]", - "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]", - "logs": "[parameters('logs')]", - "metrics": "[parameters('metrics')]" - } - } - ] - } - } - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[and(parameters('deployPolicy'), not(empty(parameters('virtualNetworkAddressPrefix'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('assign-policy-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "location": { - "value": "[parameters('location')]" - }, - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "tiers": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value]" - }, - "policy": { - "value": "[parameters('policy')]" - }, - "resourceGroupNames": { - "value": [ - "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - ] - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "2239324965165269347" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "location": { - "type": "string" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "policy": { - "type": "string" - }, - "resourceGroupNames": { - "type": "array" - }, - "tiers": { - "type": "array" - } - }, - "resources": [ - { - "copy": { - "name": "policyAssignment", - "count": "[length(parameters('tiers'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('assign-policy-{0}-{1}', parameters('tiers')[copyIndex()].name, parameters('deploymentNameSuffix'))]", - "subscriptionId": "[parameters('tiers')[copyIndex()].subscriptionId]", - "resourceGroup": "[parameters('resourceGroupNames')[copyIndex()]]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "builtInAssignment": { - "value": "[parameters('policy')]" - }, - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "location": { - "value": "[parameters('location')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "16715470716191237776" - } - }, - "parameters": { - "builtInAssignment": { - "type": "string", - "defaultValue": "NISTRev4", - "allowedValues": [ - "NISTRev4", - "NISTRev5", - "IL5", - "CMMC" - ], - "metadata": { - "description": "[NISTRev4/NISTRev5/IL5/CMMC] Built-in policy assignments to assign, default is NISTRev4. IL5 is only available for AzureUsGovernment and will switch to NISTRev4 if tried in AzureCloud." - } - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "deployRemediation": { - "type": "bool", - "defaultValue": false, - "metadata": { - "description": "Starts a policy remediation for the VM Agent policies in hub RG. Set to false by default since this is time consuming in deployment." - } - }, - "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]", - "metadata": { - "description": "The location of this resource" - } - } - }, - "variables": { - "$fxv#0": " {\r\n \"listOfMembersToExcludeFromWindowsVMAdministratorsGroup\": \r\n {\r\n \"value\": \"admin\"\r\n },\r\n \"listOfMembersToIncludeInWindowsVMAdministratorsGroup\": \r\n {\r\n \"value\": \"azureuser\"\r\n },\r\n \"logAnalyticsWorkspaceIdforVMReporting\": \r\n {\r\n \"value\": \"\"\r\n },\r\n \"IncludeArcMachines\": \r\n {\r\n \"value\": \"true\"\r\n },\r\n \"MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112\": \r\n {\r\n \"value\": \"1.2\"\r\n },\r\n \"NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40\": \r\n {\r\n \"value\": \"Compliant\"\r\n },\r\n \"requiredRetentionDays\": \r\n {\r\n \"value\": \"365\"\r\n },\r\n \"resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6\": \r\n {\r\n \"value\": \"NetworkWatcherRG\"\r\n }\r\n }", - "$fxv#1": " {\r\n \"IncludeArcMachines\": \r\n {\r\n \"value\": \"true\"\r\n },\r\n \"MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112\": \r\n {\r\n \"value\": \"1.2\"\r\n },\r\n \"NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40\": \r\n {\r\n \"value\": \"Compliant\"\r\n },\r\n \"requiredRetentionDays\": \r\n {\r\n \"value\": \"365\"\r\n },\r\n \"resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6\": \r\n {\r\n \"value\": \"NetworkWatcherRG\"\r\n }\r\n }", - "$fxv#2": "{\r\n \"IncludeArcMachines\" : { \r\n \"value\" : \"false\"\r\n },\r\n \"NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40\" : { \r\n \"value\" : \"Compliant\"\r\n },\r\n \"MinimumTLSVersionForWindowsServers\" : { \r\n \"value\" : \"1.2\"\r\n },\r\n \"requiredRetentionDays\" : { \r\n \"value\" : \"365\"\r\n },\r\n \"effect-febd0533-8e55-448f-b837-bd0e06f16469\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"allowedContainerImagesRegex-febd0533-8e55-448f-b837-bd0e06f16469\" : { \r\n \"value\" : \"^(.+){0}$\"\r\n },\r\n \"effect-95edb821-ddaf-4404-9732-666045e056b4\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-440b515e-a580-421e-abeb-b159a61ddcbc\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-233a2a17-77ca-4fb1-9b6b-69223d272a44\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-e345eecc-fa47-480f-9e88-67dcc122b164\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"cpuLimit-e345eecc-fa47-480f-9e88-67dcc122b164\" : { \r\n \"value\" : \"0\"\r\n },\r\n \"memoryLimit-e345eecc-fa47-480f-9e88-67dcc122b164\" : { \r\n \"value\" : \"0\"\r\n },\r\n \"effect-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"runAsUserRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"MustRunAsNonRoot\"\r\n },\r\n \"runAsGroupRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"RunAsAny\"\r\n },\r\n \"supplementalGroupsRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"RunAsAny\"\r\n },\r\n \"fsGroupRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"RunAsAny\"\r\n },\r\n \"effect-1c6e92c9-99f0-4e55-9cf2-0c234dc48f99\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-47a1ee2f-2a2a-4576-bf2a-e0e36709c2b8\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-df49d893-a74c-421d-bc95-c663042e5b80\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-c26596ff-4d70-4e6a-9a30-c2506bd2f80c\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-511f5417-5d12-434d-ab2e-816901e72a5e\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-82985f06-dc18-4a48-bc1c-b9f4f0098cfe\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-098fc59e-46c7-4d99-9b16-64990e543d75\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"NetworkWatcherResourceGroupName\" : { \r\n \"value\" : \"NetworkWatcherRG\"\r\n },\r\n \"setting-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9\" : { \r\n \"value\" : \"enabled\"\r\n },\r\n \"aadAuthenticationInServiceFabricMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-71ef260a-8f18-47b7-abcb-62d0673d94dc\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-055aa869-bc98-4af8-bafc-23f1ab6ffe2c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-564feb30-bf6a-4854-b4bb-0d2d2d1e6c66\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-862e97cf-49fc-4a5c-9de4-40d4e2e7c8eb\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d9da03a1-f3c3-412a-9709-947156872263\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-617c02be-7f02-4efd-8836-3180d47b6c68\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0b60c0b2-2dc2-4e1c-b5c9-abbed971de53\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ec068d99-e9c7-401f-8cef-5bdde4e6ccf1\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c349d81b-9985-44ae-a8da-ff98d108ede8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-3657f5a0-770e-44a3-b44e-9431ba1e9735\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-b4ac1030-89c5-4697-8e00-28b5ba6a8811\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-ea0dfaed-95fb-448c-934e-d6e713ce393d\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-4733ea7b-a883-42fe-8cac-97454c2a9e4a\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-f4b53539-8df9-40e4-86c6-6b607703bd4e\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-41425d9f-d1a5-499a-9932-f8ed8453932c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-fc4d8e41-e223-45ea-9bf5-eada37891d87\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-86efb160-8de7-451d-bc08-5d475b0aadae\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-4ec52d6d-beb7-40c4-9a9e-fe753254690e\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-64d314f6-6062-4780-a861-c23e8951bee5\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1fd32ebd-e4c3-4e13-a54a-d7422d4d95f6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-fa298e57-9444-42ba-bf04-86e8470e32c7\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-67121cc7-ff39-4ab8-b7e3-95b84dab487d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1f905d99-2ab7-462c-a6b0-f709acca6c8f\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-5b9159ae-1701-4a6f-9a7a-aa9c8ddd0580\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ba769a63-b8cc-4b2d-abf6-ac33c7204be8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-81e74cea-30fd-40d5-802f-d72103c2aaaa\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0aa61e00-0a01-4a3c-9945-e93cffedf0e6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-47031206-ce96-41f8-861b-6a915f3de284\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-87ba29ef-1ab3-4d82-b763-87fcd4f531f7\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-51522a96-0869-4791-82f3-981000c2c67f\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-b5ec538c-daa0-4006-8596-35468b9148e8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-56a5ee18-2ae6-4810-86f7-18e39ce5629b\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-2e94d99a-8a36-4563-bc77-810d8893b671\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1fafeaf6-7927-4059-a50a-8eb2a7a6f2b5\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-99e9ccd8-3db9-4592-b0d1-14b1715a4d8a\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1f68a601-6e6d-4e42-babf-3f643a047ea2\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-f7d52b2d-e161-4dfa-a82b-55e564167385\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7d7be79c-23ba-4033-84dd-45e2a5ccdd67\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ca91455f-eace-4f96-be59-e6e2c35b4816\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-702dd420-7fcc-42c5-afe8-4026edd20fe0\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"diagnosticsLogsInRedisCacheMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"secureTransferToStorageAccountMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d0793b48-0edc-4296-a390-4c75d1bdfd71\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7d092e0a-7acd-40d2-a975-dca21cae48c4\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-2a1a9cdf-e04d-429a-8416-3bfb72a1b26f\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"disableUnrestrictedNetworkToStorageAccountMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-55615ac9-af46-4a59-874e-391cc3dfb490\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1b8ca024-1d5c-4dec-8995-b1a932b41780\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-037eea7a-bd0a-46c5-9a66-03aea78705d3\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-53503636-bcc9-4748-9663-5348217f160f\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-40cec1dd-a100-4920-b15b-3024fe8901ab\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0725b4dd-7e76-479c-a735-68e7ee23d5ca\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-a049bf77-880b-470f-ba6d-9f21c530cf83\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ee980b6d-0eca-4501-8d54-f6290fd512c3\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1d84d5fb-01f6-4d12-ba4f-4a26081d403d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-37e0d2fe-28a5-43d6-a273-67d37d1f5606\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"identityDesignateMoreThanOneOwnerMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"diskEncryptionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"emailNotificationToSubscriptionOwnerHighSeverityAlertsEnabledEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"functionAppDisableRemoteDebuggingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"sqlDbEncryptionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vulnerabilityAssessmentOnManagedInstanceMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePHPVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"aadAuthenticationInSqlServerMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vmssEndpointProtectionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vmssOsVulnerabilitiesMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"adaptiveApplicationControlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"geoRedundantBackupShouldBeEnabledForAzureDatabaseForPostgreSQLEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"ensureJavaVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityDesignateLessThanOwnersMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"securityContactEmailAddressForSubscriptionEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"webAppRestrictCORSAccessMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveExternalAccountWithWritePermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveExternalAccountWithReadPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveDeprecatedAccountMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"functionAppEnforceHttpsMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"ensurePythonVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePythonVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePHPVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePythonVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"geoRedundantBackupShouldBeEnabledForAzureDatabaseForMySQLEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"systemUpdatesMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureJavaVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureHTTPVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"apiAppRequireLatestTlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityEnableMFAForWritePermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureHTTPVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureJavaVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"nextGenerationFirewallMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"useRbacRulesMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"webAppEnforceHttpsMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"sqlServerAuditingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vnetEnableDDoSProtectionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityEnableMFAForOwnerPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"sqlServerAdvancedDataSecurityMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"sqlManagedInstanceAdvancedDataSecurityMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"endpointProtectionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"jitNetworkAccessMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"apiAppEnforceHttpsMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"geoRedundantStorageShouldBeEnabledForStorageAccountsEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"vmssSystemUpdatesMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"webAppDisableRemoteDebuggingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"longtermGeoRedundantBackupEnabledAzureSQLDatabasesEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"systemConfigurationsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureHTTPVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityEnableMFAForReadPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"containerBenchmarkMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"apiAppDisableRemoteDebuggingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveDeprecatedAccountWithOwnerPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vulnerabilityAssessmentOnServerMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"webAppRequireLatestTlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveExternalAccountWithOwnerPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"functionAppRequireLatestTlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"kubernetesServiceVersionUpToDateMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"sqlDbVulnerabilityAssesmentMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"membersToIncludeInLocalAdministratorsGroup\" : { \r\n \"value\" : \"\"\r\n },\r\n \"membersToExcludeInLocalAdministratorsGroup\" : { \r\n \"value\" : \"\"\r\n },\r\n \"logAnalyticsWorkspaceIDForVMAgents\" : { \r\n \"value\" : \"\"\r\n },\r\n \"PHPLatestVersionForAppServices\" : { \r\n \"value\" : \"7.4\"\r\n },\r\n \"JavaLatestVersionForAppServices\" : { \r\n \"value\" : \"11\"\r\n },\r\n \"WindowsPythonLatestVersionForAppServices\" : { \r\n \"value\" : \"3.6\"\r\n },\r\n \"LinuxPythonLatestVersionForAppServices\" : { \r\n \"value\" : \"3.9\"\r\n },\r\n \"ensureDotNetFrameworkLatestForFunctionAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlManagedInstanceAdvancedDataSecurityEmailsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"vulnerabilityAssessmentMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"ensureDotNetFrameworkLatestForWebAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlServerAdvancedDataSecurityEmailsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"microsoftIaaSAntimalwareExtensionShouldBeDeployedOnWindowsServersEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"securityCenterStandardPricingTierShouldBeSelectedEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"theLogAnalyticsAgentShouldBeInstalledOnVirtualMachinesEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"ensurePHPVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlManagedInstanceAdvancedDataSecurityEmailAdminsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"securityContactPhoneNumberShouldBeProvidedForSubscriptionEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"threatDetectionTypesOnManagedInstanceMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"ensureDotNetFrameworkLatestForAPIAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlServerAdvancedDataSecurityEmailAdminsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"threatDetectionTypesOnServerMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"theLogAnalyticsAgentShouldBeInstalledOnVirtualMachineScaleSetsEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n }\r\n}", - "$fxv#3": "{\r\n \"logAnalyticsWorkspaceId-f47b5582-33ec-4c5c-87c0-b010a6b2e917\" : { \r\n \"value\" : \"\"\r\n },\r\n \"effect-09024ccc-0c5f-475e-9457-b7c0d9ed487b\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"MembersToExclude-69bf4abd-ca1e-4cf6-8b5a-762d42e61d4f\" :{\r\n \"value\": \"\"\r\n },\r\n \"MembersToInclude-30f71ea1-ac77-4f26-9fc5-2d926bbd4ba7\": {\r\n \"value\": \"\"\r\n },\r\n \"effect-0961003e-5a0a-4549-abde-af6a37f2724d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0b15565f-aa9e-48ba-8619-45960f2c314d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0e60b895-3786-45da-8377-9c6b4b6ac5f9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-17k78e20-9358-41c9-923c-fb736d382a12\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-1bc1795e-d44a-4d48-9b3b-6fff0fd5f9ba\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"PHPLatestVersion\" : { \r\n \"value\" : \"7.3\"\r\n },\r\n \"effect-22bee202-a82f-4305-9a2a-6d7f44d4dedb\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-26a828e1-e88f-464e-bbb3-c134a282b9de\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-34c877ad-507e-4c82-993e-3452a6e0ad3c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-3c735d8a-a4ba-4a3a-b7cf-db7754cf57f4\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-404c3081-a854-4457-ae30-26a93ef643f9\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-47a6b606-51aa-4496-8bb7-64b11cf66adc\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-496223c3-ad65-4ecd-878a-bae78737e9ed\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"JavaLatestVersion\" : { \r\n \"value\" : \"11\"\r\n },\r\n \"effect-4f11b553-d42e-4e3a-89be-32ca364cad4c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-4f4f78b8-e367-4b10-a341-d9a4ad5cf1c7\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-5c607a2e-c700-4744-8254-d77e7c9eb5e4\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-5f76cf89-fbf2-47fd-a3f4-b891fa780b60\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-6b1cbf55-e8b6-442f-ba4c-7246b6381474\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-6d555dd1-86f2-4f1c-8ed7-5abae7c6cbab\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7008174a-fd10-4ef0-817e-fc820a951d73\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"LinuxPythonLatestVersion\" : { \r\n \"value\" : \"3.8\"\r\n },\r\n \"effect-7238174a-fd10-4ef0-817e-fc820a951d73\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-7261b898-8a84-4db8-9e04-18527132abb3\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-74c3584d-afae-46f7-a20a-6f8adba71a16\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-86b3d65f-7626-441e-b690-81a8b71cff60\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-88999f4c-376a-45c8-bcb3-4058f713cf39\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-8c122334-9d20-4eb8-89ea-ac9a705b74ae\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-8cb6aa8b-9e41-4f4e-aa25-089a7ac2581e\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9297c21d-2ed6-4474-b48f-163f75654ce3\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-991310cd-e9f3-47bc-b7b6-f57b557d07db\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9b597639-28e4-48eb-b506-56b05d366257\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9d0b6ea4-93e2-4578-bf2f-6bb17d22b4bc\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9daedab3-fb2d-461e-b861-71790eead4f6\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-a4af4a39-4135-47fb-b175-47fbdf85311d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"setting-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9\" : { \r\n \"value\" : \"enabled\"\r\n },\r\n \"effect-a70ca396-0a34-413a-88e1-b956c1e683be\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-aa633080-8b72-40c4-a2d7-d00c03e80bed\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-abfb4388-5bf4-4ad7-ba82-2cd2f41ceae9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-abfb7388-5bf4-4ad7-ba99-2cd2f41cebb9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-af6cd1bd-1635-48cb-bde7-5b15693900b9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6\" : { \r\n \"value\" : \"NetworkWatcherRG\"\r\n },\r\n \"effect-b7ddfbdc-1260-477d-91fd-98bd9be789a6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c3f317a7-a95c-4547-b7e7-11017ebdf2fe\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-cb510bfd-1cba-4d9f-a230-cb0976f4bb71\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e1e5fd5d-3e4c-4ce1-8661-7d1873ae6b15\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e2c1c086-2d84-4019-bff3-c44ccd95113c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e3576e28-8b17-4677-84c3-db2990658d64\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e8cbc669-f12d-49eb-93e7-9273119e9933\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e9c8d085-d9cc-4b17-9cdc-059f1f01f19e\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ebb62a0c-3560-49e1-89ed-27e074e9f8ad\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-efbde977-ba53-4479-b8e9-10b957924fbf\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f0e6e85b-9b9f-4a4b-b67b-f730d42f1b0b\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f6de0be7-9a8a-4b8a-b349-43cf02d22f7c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f8456c1c-aa66-4dfb-861a-25d127b775c9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f9d614c5-c173-4d56-95a7-b4437057d193\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-fb893a29-21bb-418c-a157-e99480ec364c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-feedbf84-6b99-488c-acc2-71c829aa5ffc\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-3b980d31-7904-4bb7-8575-5665739a8052\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-6e2593d9-add6-4083-9c9b-4b7d2188c899\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b607c5de-e7d9-4eee-9e5c-83f1bcee4fa0\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-12430be1-6cc8-4527-a9a8-e3d38f250096\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"modeRequirement-12430be1-6cc8-4527-a9a8-e3d38f250096\" : { \r\n \"value\" : \"Detection\"\r\n },\r\n \"effect-425bea59-a659-4cbb-8d31-34499bd030b8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"modeRequirement-425bea59-a659-4cbb-8d31-34499bd030b8\" : { \r\n \"value\" : \"Detection\"\r\n },\r\n \"effect-564feb30-bf6a-4854-b4bb-0d2d2d1e6c66\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-055aa869-bc98-4af8-bafc-23f1ab6ffe2c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-013e242c-8828-4970-87b3-ab247555486d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-d38fc420-0735-4ef3-ac11-c806f651a570\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-a1181c5f-672a-477a-979a-7d58aa086233\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-308fbb08-4ab8-4e67-9b29-592e93fb94fa\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-4da35fc9-c9e7-4960-aec9-797fe7d9051d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-523b5cd1-3e23-492f-a539-13118b6d1e3a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-7fe3b40f-802b-4cdd-8bd4-fd799c948cc2\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-c25d9a16-bc35-4e15-a7e5-9db606bf9ed4\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b0f33259-77d7-4c9e-aac6-3aabcfae693c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-037eea7a-bd0a-46c5-9a66-03aea78705d3\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0725b4dd-7e76-479c-a735-68e7ee23d5ca\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0820b7b9-23aa-4725-a1ce-ae4558f718e5\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-2c89a2e5-7285-40fe-afe0-ae8654b92fab\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-358c20a6-3f9e-4f0e-97ff-c6ce485e2aac\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-5744710e-cc2f-4ee8-8809-3b11e89f4bc9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ac4a19c2-fa67-49b4-8ae5-0b2e78c49457\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c9d007d0-c057-4772-b18c-01e546713bcd\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d0793b48-0edc-4296-a390-4c75d1bdfd71\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-e372f825-a257-4fb8-9175-797a8a8627d6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d158790f-bfb0-486c-8631-2dc6b4e8e6af\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-e802a67a-daf5-4436-9ea6-f6d821dd0c5d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-a451c1ef-c6ca-483d-87ed-f49761e3ffb5\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftSql-servers-firewallRules-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftNetwork-networkSecurityGroups-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftClassicNetwork-networkSecurityGroups-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftNetwork-networkSecurityGroups-securityRules-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftClassicNetwork-networkSecurityGroups-securityRules-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ae89ebca-1c92-4898-ac2c-9f63decb045c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-d26f7642-7545-4e18-9b75-8c9bbdee3a9a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-1a4e592a-6a6e-44a5-9814-e36264ca96e7\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-7796937f-307b-4598-941c-67d3a05ebfe7\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-c5447c04-a4d7-4ba8-a263-c9ee321a6858\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-41388f1c-2db0-4c25-95b2-35d7f5ccbfa9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b02aacc0-b073-424e-8298-42b22829ee0a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-057d6cfe-9c4f-4a6d-bc60-14420ea1f1a9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0ec47710-77ff-4a3d-9181-6aa50af424d0\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-48af4db5-9b8b-401c-8e74-076be876a430\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-82339799-d096-41ae-8538-b108becf0970\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1b7aa243-30e4-4c9e-bca8-d0d3022b634a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ef2a8f2a-b3d9-49cd-a8a8-9a3aaaf647d9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-bb91dfba-c30d-4263-9add-9c2384e659a6\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e71308d3-144b-4262-b144-efdc3cc90517\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-2bdd0062-9d75-436e-89df-487dd8e4b3c7\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"effect-4733ea7b-a883-42fe-8cac-97454c2a9e4a\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-67121cc7-ff39-4ab8-b7e3-95b84dab487d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-6fac406b-40ca-413b-bf8e-0bf964659c25\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-81e74cea-30fd-40d5-802f-d72103c2aaaa\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c349d81b-9985-44ae-a8da-ff98d108ede8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-f4b53539-8df9-40e4-86c6-6b607703bd4e\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ec068d99-e9c7-401f-8cef-5bdde4e6ccf1\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-048248b0-55cd-46da-b1ff-39efd52db260\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0d134df8-db83-46fb-ad72-fe0c9428c8dd\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-2c89a2e5-7285-40fe-afe0-ae8654b92fb2\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-3657f5a0-770e-44a3-b44e-9431ba1e9735\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-5b9159ae-1701-4a6f-9a7a-aa9c8ddd0580\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-617c02be-7f02-4efd-8836-3180d47b6c68\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7d7be79c-23ba-4033-84dd-45e2a5ccdd67\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-87ba29ef-1ab3-4d82-b763-87fcd4f531f7\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-f7d52b2d-e161-4dfa-a82b-55e564167385\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c43e4a30-77cb-48ab-a4dd-93f175c63b57\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0b60c0b2-2dc2-4e1c-b5c9-abbed971de53\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1f314764-cb73-4fc9-b863-8eca98ac36e9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-123a3936-f020-408a-ba0c-47873faf1534\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n }\r\n}\r\n", - "modifiedAssignment": "[if(and(equals(toLower(environment().name), toLower('AzureCloud')), equals(toLower(parameters('builtInAssignment')), toLower('IL5'))), 'NISTRev4', parameters('builtInAssignment'))]", - "assignmentName": "[format('{0} {1}', variables('modifiedAssignment'), resourceGroup().name)]", - "agentVmssAssignmentName": "[format('Deploy VMSS Agents {0}', resourceGroup().name)]", - "agentVmAssignmentName": "[format('Deploy VM Agents {0}', resourceGroup().name)]", - "contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", - "lawsReaderRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]" - }, - "resources": [ - { - "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2020-09-01", - "name": "[variables('assignmentName')]", - "location": "[parameters('location')]", - "properties": { - "policyDefinitionId": "[createObject('NISTRev4', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/cf25b9c1-bd23-4eb6-bd2c-f4f3ac644a5f', 'parameters', json(replace(variables('$fxv#0'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'NISTRev5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/179d1daa-458f-4e47-8086-2a68d0d6c38f', 'parameters', json(variables('$fxv#1'))), 'IL5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/f9a961fa-3241-4b20-adc4-bbf8ad9d7197', 'parameters', json(replace(variables('$fxv#2'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'CMMC', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/b5629c75-5c77-4422-87b9-2509e680f8de', 'parameters', json(replace(variables('$fxv#3'), '', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]), '2021-06-01').customerId))))[variables('modifiedAssignment')].id]", - "parameters": "[createObject('NISTRev4', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/cf25b9c1-bd23-4eb6-bd2c-f4f3ac644a5f', 'parameters', json(replace(variables('$fxv#0'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'NISTRev5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/179d1daa-458f-4e47-8086-2a68d0d6c38f', 'parameters', json(variables('$fxv#1'))), 'IL5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/f9a961fa-3241-4b20-adc4-bbf8ad9d7197', 'parameters', json(replace(variables('$fxv#2'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'CMMC', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/b5629c75-5c77-4422-87b9-2509e680f8de', 'parameters', json(replace(variables('$fxv#3'), '', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]), '2021-06-01').customerId))))[variables('modifiedAssignment')].parameters]" - }, - "identity": { - "type": "SystemAssigned" - } - }, - { - "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2020-09-01", - "name": "[variables('agentVmssAssignmentName')]", - "location": "[parameters('location')]", - "properties": { - "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policySetDefinitions', '75714362-cae7-409e-9b99-a8e5075b7fad')]", - "parameters": { - "logAnalytics_1": { - "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])]" - } - } - }, - "identity": { - "type": "SystemAssigned" - } - }, - { - "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2020-09-01", - "name": "[variables('agentVmAssignmentName')]", - "location": "[parameters('location')]", - "properties": { - "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policySetDefinitions', '55f3eceb-5573-4f18-9695-226972c6d74a')]", - "parameters": { - "logAnalytics_1": { - "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])]" - } - } - }, - "identity": { - "type": "SystemAssigned" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(variables('contributorRoleDefinitionId'), variables('assignmentName'))]", - "properties": { - "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", - "principalId": "[if(empty(variables('modifiedAssignment')), '', reference(resourceId('Microsoft.Authorization/policyAssignments', variables('assignmentName')), '2020-09-01', 'full').identity.principalId)]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.Authorization/policyAssignments', variables('assignmentName'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(variables('contributorRoleDefinitionId'), variables('agentVmssAssignmentName'))]", - "properties": { - "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", - "principalId": "[reference(resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmssAssignmentName')), '2020-09-01', 'full').identity.principalId]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmssAssignmentName'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(variables('contributorRoleDefinitionId'), variables('agentVmAssignmentName'))]", - "properties": { - "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", - "principalId": "[reference(resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName')), '2020-09-01', 'full').identity.principalId]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]" - ] - }, - { - "condition": "[parameters('deployRemediation')]", - "type": "Microsoft.PolicyInsights/remediations", - "apiVersion": "2019-07-01", - "name": "VM-Agent-Policy-Remediation", - "properties": { - "policyAssignmentId": "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]", - "resourceDiscoveryMode": "ReEvaluateCompliance" - }, - "dependsOn": [ - "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('Assign-Laws-Role-Policy-{0}', resourceGroup().name)]", - "subscriptionId": "[split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2]]", - "resourceGroup": "[split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "targetResourceId": { - "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])]" - }, - "roleDefinitionId": { - "value": "[variables('lawsReaderRoleDefinitionId')]" - }, - "principalId": { - "value": "[reference(resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName')), '2020-09-01', 'full').identity.principalId]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "967013811257719495" - } - }, - "parameters": { - "targetResourceId": { - "type": "string" - }, - "roleDefinitionId": { - "type": "string" - }, - "principalId": { - "type": "string" - }, - "principalType": { - "type": "string", - "defaultValue": "ServicePrincipal", - "allowedValues": [ - "ForeignGroup", - "Group", - "ServicePrincipal", - "User" - ] - }, - "description": { - "type": "string", - "defaultValue": "" - } - }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "name": "[guid(parameters('targetResourceId'), parameters('roleDefinitionId'), parameters('principalId'))]", - "properties": { - "principalId": "[parameters('principalId')]", - "principalType": "[parameters('principalType')]", - "roleDefinitionId": "[parameters('roleDefinitionId')]", - "description": "[parameters('description')]" - } - } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]" - ] - } - ] - } - } - } - ] - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" - ] - }, - { - "condition": "[and(parameters('deployDefender'), not(empty(parameters('virtualNetworkAddressPrefix'))))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('set-defender-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "emailSecurityContact": { - "value": "[parameters('emailSecurityContact')]" - }, - "logAnalyticsWorkspaceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "2575529544484247921" - } - }, - "parameters": { - "defenderPlans": { - "type": "array", - "defaultValue": [ - "VirtualMachines" - ], - "metadata": { - "description": "Defender Paid protection Plans. Even if a customer selects the free sku, at least 1 paid protection plan must be specified." - } - }, - "enableAutoProvisioning": { - "type": "bool", - "defaultValue": true, - "metadata": { - "description": "Turn automatic deployment by Defender of the MMA (OMS VM extension) on or off" - } - }, - "logAnalyticsWorkspaceId": { - "type": "string", - "metadata": { - "description": "Specify the ID of your custom Log Analytics workspace to collect Defender data." - } - }, - "emailSecurityContact": { - "type": "string", - "metadata": { - "description": "Email address of the contact, in the form of john@doe.com" - } - }, - "policySetDescription": { - "type": "string", - "defaultValue": "The Microsoft Cloud Security Benchmark initiative represents the policies and controls implementing security recommendations defined in Microsoft Cloud Security Benchmark v2, see https://aka.ms/azsecbm. This also serves as the Microsoft Defender for Cloud default policy initiative. You can directly assign this initiative, or manage its policies and compliance results within Microsoft Defender.", - "metadata": { - "description": "Policy Initiative description field" - } - }, - "defenderSkuTier": { - "type": "string", - "defaultValue": "Free", - "metadata": { - "description": "[Standard/Free] The SKU for Defender. It defaults to \"Free\"." - } - } - }, - "variables": { - "autoProvisioning": "[if(parameters('enableAutoProvisioning'), 'On', 'Off')]", - "defenderPaidPlanConfig": { - "AzureCloud": { - "Api": { - "subPlan": "P1" - }, - "appServices": {}, - "KeyVaults": { - "subPlan": "PerKeyVault" - }, - "Arm": { - "subPlan": "PerSubscription" - }, - "CloudPosture": { - "extensions": [ - { - "name": "SensitiveDataDiscovery", - "isEnabled": "True" - }, - { - "name": "ContainerRegistriesVulnerabilityAssessments", - "isEnabled": "True" - }, - { - "name": "AgentlessDiscoveryForKubernetes", - "isEnabled": "True" - }, - { - "name": "AgentlessVmScanning", - "isEnabled": "True" - }, - { - "name": "EntraPermissionsManagement", - "isEnabled": "True" - } - ] - }, - "Containers": { - "extensions": [ - { - "name": "ContainerRegistriesVulnerabilityAssessments", - "isEnabled": "True" - }, - { - "name": "AgentlessDiscoveryForKubernetes", - "isEnabled": "True" - } - ] - }, - "CosmosDbs": {}, - "StorageAccounts": { - "subPlan": "DefenderForStorageV2", - "extensions": [ - { - "name": "OnUploadMalwareScanning", - "isEnabled": "True", - "additionalExtensionProperties": { - "CapGBPerMonthPerStorageAccount": "5000" - } - }, - { - "name": "SensitiveDataDiscovery", - "isEnabled": "True" - } - ] - }, - "VirtualMachines": { - "subPlan": "P1" - }, - "SqlServerVirtualMachines": {}, - "SqlServers": {}, - "OpenSourceRelationalDatabases": {} - } - } - }, - "resources": [ - { - "copy": { - "name": "defenderFreeAllClouds", - "count": "[length(parameters('defenderPlans'))]", - "mode": "serial", - "batchSize": 1 - }, - "condition": "[equals(parameters('defenderSkuTier'), 'Free')]", - "type": "Microsoft.Security/pricings", - "apiVersion": "2023-01-01", - "name": "[parameters('defenderPlans')[copyIndex()]]", - "properties": { - "pricingTier": "[parameters('defenderSkuTier')]" - } - }, - { - "copy": { - "name": "defenderStandardNoSubplanNoExtensions", - "count": "[length(parameters('defenderPlans'))]", - "mode": "serial", - "batchSize": 1 - }, - "condition": "[and(equals(parameters('defenderSkuTier'), 'Standard'), not(equals(environment().name, 'AzureCloud')))]", - "type": "Microsoft.Security/pricings", - "apiVersion": "2023-01-01", - "name": "[parameters('defenderPlans')[copyIndex()]]", - "properties": { - "pricingTier": "[parameters('defenderSkuTier')]" - } - }, - { - "copy": { - "name": "defenderStandardSubplanExtensionsAzureCloud", - "count": "[length(parameters('defenderPlans'))]", - "mode": "serial", - "batchSize": 1 - }, - "condition": "[and(equals(parameters('defenderSkuTier'), 'Standard'), equals(environment().name, 'AzureCloud'))]", - "type": "Microsoft.Security/pricings", - "apiVersion": "2023-01-01", - "name": "[parameters('defenderPlans')[copyIndex()]]", - "properties": { - "pricingTier": "[parameters('defenderSkuTier')]", - "subPlan": "[if(contains(variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]], 'subPlan'), variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]].subPlan, json('null'))]", - "extensions": "[if(contains(variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]], 'extensions'), variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]].extensions, json('null'))]" - } - }, - { - "type": "Microsoft.Security/autoProvisioningSettings", - "apiVersion": "2019-01-01", - "name": "default", - "properties": { - "autoProvision": "[variables('autoProvisioning')]" - } - }, - { - "type": "Microsoft.Security/workspaceSettings", - "apiVersion": "2019-01-01", - "name": "default", - "properties": { - "workspaceId": "[parameters('logAnalyticsWorkspaceId')]", - "scope": "[subscription().id]" - } - }, - { - "condition": "[not(empty(parameters('emailSecurityContact')))]", - "type": "Microsoft.Security/securityContacts", - "apiVersion": "2020-01-01-preview", - "name": "default", - "properties": { - "notificationsByRole": { - "roles": [ - "AccountAdmin", - "Contributor", - "Owner", - "ServiceAdmin" - ], - "state": "On" - }, - "alertNotifications": { - "state": "On" - }, - "emails": "[parameters('emailSecurityContact')]" - } - }, - { - "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2022-06-01", - "name": "Microsoft Cloud Security Benchmark", - "properties": { - "displayName": "Defender Default", - "description": "[parameters('policySetDescription')]", - "enforcementMode": "DoNotEnforce", - "parameters": {}, - "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policySetDefinitions', '1f3afdf9-d0c9-4c3d-847f-89da613e70a8')]" - } - } - ] - } - } - } - ], - "outputs": { - "diskEncryptionSetResourceId": { - "type": "string", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskEncryptionSetResourceId.value, '')]" - }, - "dnsServers": { - "type": "array", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), coalesce(tryGet(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01'), 'dhcpOptions', 'dnsServers'), createArray()), createArray())]" - }, - "keyVaultUri": { - "type": "string", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value, '')]" - }, - "locationProperties": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value]" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "mlzTags": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "namingConvention": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention]" - }, - "privateDnsZones": { - "type": "array", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value]" - }, - "resourceAbbreviations": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" - }, - "resourcePrefix": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('firewallResourceId'), '/')[2], split(parameters('firewallResourceId'), '/')[4]), 'Microsoft.Network/azureFirewalls', split(parameters('firewallResourceId'), '/')[8]), '2020-11-01', 'full').tags.resourcePrefix]" - }, - "storageAccountResourceId": { - "type": "string", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageAccountResourceId.value, '')]" - }, - "storageEncryptionKeyName": { - "type": "string", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageKeyName.value, '')]" - }, - "subnets": { - "type": "array", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value, createArray())]" - }, - "tier": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" - }, - "tokens": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value]" - }, - "userAssignedIdentityResourceId": { - "type": "string", - "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.userAssignedIdentityResourceId.value, '')]" - } - } - } - } - }, - { - "copy": { - "name": "rgs", - "count": "[length(variables('resourceGroupServices'))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[copyIndex()], parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": "[if(equals(variables('resourceGroupServices')[copyIndex()], 'controlPlane'), createObject('value', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location), createObject('value', parameters('locationVirtualMachines')))]", - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "name": "[if(equals(variables('resourceGroupServices')[copyIndex()], 'controlPlane'), createObject('value', replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, variables('resourceGroupServices')[copyIndex()])), createObject('value', replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, variables('resourceGroupServices')[copyIndex()])))]", - "tags": { - "value": "[parameters('tags')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "17445726037807437290" - } - }, - "parameters": { - "mlzTags": { - "type": "object" - }, - "name": { - "type": "string" - }, - "location": { - "type": "string" - }, - "tags": { - "type": "object", - "defaultValue": {} - } - }, - "resources": [ - { - "type": "Microsoft.Resources/resourceGroups", - "apiVersion": "2019-05-01", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Resources/resourceGroups'), parameters('tags')['Microsoft.Resources/resourceGroups'], createObject()), parameters('mlzTags'))]" - } - ], - "outputs": { - "id": { - "type": "string", - "value": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name'))]" - }, - "name": { - "type": "string", - "value": "[parameters('name')]" - }, - "location": { - "type": "string", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name')), '2019-05-01', 'full').location]" - }, - "tags": { - "type": "object", - "value": "[reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name')), '2019-05-01', 'full').tags]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-management-{0}', parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "avdObjectId": { - "value": "[parameters('avdObjectId')]" - }, - "deployFslogix": { - "value": "[variables('deployFslogix')]" - }, - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "diskEncryptionSetResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskEncryptionSetResourceId.value]" - }, - "diskSku": { - "value": "[parameters('diskSku')]" - }, - "domainJoinPassword": { - "value": "[parameters('domainJoinPassword')]" - }, - "domainJoinUserPrincipalName": { - "value": "[parameters('domainJoinUserPrincipalName')]" - }, - "domainName": { - "value": "[parameters('domainName')]" - }, - "enableApplicationInsights": { - "value": "[parameters('enableApplicationInsights')]" - }, - "enableAvdInsights": { - "value": "[parameters('enableAvdInsights')]" - }, - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" - }, - "fslogixStorageService": { - "value": "[parameters('fslogixStorageService')]" - }, - "locationVirtualMachines": { - "value": "[parameters('locationVirtualMachines')]" - }, - "logAnalyticsWorkspaceRetention": { - "value": "[parameters('logAnalyticsWorkspaceRetention')]" - }, - "logAnalyticsWorkspaceSku": { - "value": "[parameters('logAnalyticsWorkspaceSku')]" - }, - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "namingConvention": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value]" - }, - "organizationalUnitPath": { - "value": "[parameters('organizationalUnitPath')]" - }, - "privateDnsZoneResourceIdPrefix": { - "value": "[variables('privateDnsZoneResourceIdPrefix')]" - }, - "privateDnsZones": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value]" - }, - "privateLinkScopeResourceId": { - "value": "[parameters('privateLinkScopeResourceId')]" - }, - "recoveryServices": { - "value": "[parameters('recoveryServices')]" - }, - "recoveryServicesGeo": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value.recoveryServicesGeo]" - }, - "resourceAbbreviations": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" - }, - "resourceGroupControlPlane": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[0], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "resourceGroupHosts": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[1], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "resourceGroupManagement": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "resourceGroupStorage": "[if(variables('deployFslogix'), createObject('value', replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'storage')), createObject('value', ''))]", - "roleDefinitions": { - "value": "[variables('roleDefinitions')]" - }, - "serviceToken": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" - }, - "storageService": { - "value": "[variables('storageService')]" - }, - "subnetResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[0].id]" - }, - "subnets": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "timeDifference": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value.timeDifference]" - }, - "timeZone": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value.timeZone]" - }, - "virtualMachinePassword": { - "value": "[parameters('virtualMachinePassword')]" - }, - "virtualMachineUsername": { - "value": "[parameters('virtualMachineUsername')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "12558774705370628238" - } - }, - "parameters": { - "avdObjectId": { - "type": "string" - }, - "deployFslogix": { - "type": "bool" - }, - "deploymentNameSuffix": { - "type": "string" - }, - "diskEncryptionSetResourceId": { - "type": "string" - }, - "diskSku": { - "type": "string" - }, - "domainJoinPassword": { - "type": "securestring" - }, - "domainJoinUserPrincipalName": { - "type": "string" - }, - "domainName": { - "type": "string" - }, - "enableApplicationInsights": { - "type": "bool" - }, - "enableAvdInsights": { - "type": "bool" - }, - "environmentAbbreviation": { - "type": "string" - }, - "fslogixStorageService": { - "type": "string" - }, - "locationVirtualMachines": { - "type": "string" - }, - "logAnalyticsWorkspaceRetention": { - "type": "int" - }, - "logAnalyticsWorkspaceSku": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "namingConvention": { - "type": "object" - }, - "organizationalUnitPath": { - "type": "string" - }, - "privateDnsZoneResourceIdPrefix": { - "type": "string" - }, - "privateDnsZones": { - "type": "array" - }, - "privateLinkScopeResourceId": { - "type": "string" - }, - "recoveryServices": { - "type": "bool" - }, - "recoveryServicesGeo": { - "type": "string" - }, - "resourceAbbreviations": { - "type": "object" - }, - "resourceGroupControlPlane": { - "type": "string" - }, - "resourceGroupHosts": { - "type": "string" - }, - "resourceGroupManagement": { - "type": "string" - }, - "resourceGroupStorage": { - "type": "string" - }, - "roleDefinitions": { - "type": "object" - }, - "serviceToken": { - "type": "string" - }, - "storageService": { - "type": "string" - }, - "subnetResourceId": { - "type": "string" - }, - "subnets": { - "type": "array" - }, - "tags": { - "type": "object" - }, - "timeDifference": { - "type": "string" + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "15810721730485220824" + } + }, + "parameters": { + "deploymentNameSuffix": { + "type": "string" + }, + "environmentAbbreviation": { + "type": "string" + }, + "location": { + "type": "string" + }, + "networks": { + "type": "array" + }, + "resourcePrefix": { + "type": "string" + }, + "stampIndex": { + "type": "string", + "defaultValue": "" + } + }, + "variables": { + "$fxv#0": "1.0.0", + "environmentName": { + "dev": "Development", + "prod": "Production", + "test": "Test" + }, + "mlzTags": { + "environment": "[variables('environmentName')[parameters('environmentAbbreviation')]]", + "landingZoneName": "MissionLandingZone", + "landingZoneVersion": "[variables('$fxv#0')]", + "resourcePrefix": "[parameters('resourcePrefix')]" + } + }, + "resources": [ + { + "copy": { + "name": "namingConventions", + "count": "[length(parameters('networks'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('naming-convention-{0}-{1}', parameters('networks')[copyIndex()].shortName, parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "environmentAbbreviation": { + "value": "[parameters('environmentAbbreviation')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "networkName": { + "value": "[parameters('networks')[copyIndex()].name]" + }, + "networkShortName": { + "value": "[parameters('networks')[copyIndex()].shortName]" + }, + "resourcePrefix": { + "value": "[parameters('resourcePrefix')]" + }, + "stampIndex": { + "value": "[parameters('stampIndex')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "11125044402666498605" + } + }, + "parameters": { + "environmentAbbreviation": { + "type": "string" + }, + "location": { + "type": "string" + }, + "networkName": { + "type": "string" + }, + "networkShortName": { + "type": "string" + }, + "resourcePrefix": { + "type": "string" + }, + "stampIndex": { + "type": "string", + "defaultValue": "" + }, + "tokens": { + "type": "object", + "defaultValue": { + "purpose": "purpose_token", + "resource": "resource_token", + "service": "service_token" + } + } + }, + "variables": { + "$fxv#0": { + "AzureChina": { + "chinaeast": { + "abbreviation": "cne", + "recoveryServicesGeo": "sha", + "timeDifference": "+8:00", + "timeZone": "China Standard Time" + }, + "chinaeast2": { + "abbreviation": "cne2", + "recoveryServicesGeo": "sha2", + "timeDifference": "+8:00", + "timeZone": "China Standard Time" + }, + "chinanorth": { + "abbreviation": "cnn", + "recoveryServicesGeo": "bjb", + "timeDifference": "+8:00", + "timeZone": "China Standard Time" + }, + "chinanorth2": { + "abbreviation": "cnn2", + "recoveryServicesGeo": "bjb2", + "timeDifference": "+8:00", + "timeZone": "China Standard Time" + } + }, + "AzureCloud": { + "australiacentral": { + "abbreviation": "auc", + "recoveryServicesGeo": "acl", + "timeDifference": "+10:00", + "timeZone": "AUS Eastern Standard Time" + }, + "australiacentral2": { + "abbreviation": "auc2", + "recoveryServicesGeo": "acl2", + "timeDifference": "+10:00", + "timeZone": "AUS Eastern Standard Time" + }, + "australiaeast": { + "abbreviation": "aue", + "recoveryServicesGeo": "ae", + "timeDifference": "+10:00", + "timeZone": "AUS Eastern Standard Time" + }, + "australiasoutheast": { + "abbreviation": "ause", + "recoveryServicesGeo": "ase", + "timeDifference": "+10:00", + "timeZone": "AUS Eastern Standard Time" + }, + "brazilsouth": { + "abbreviation": "brs", + "recoveryServicesGeo": "brs", + "timeDifference": "-3:00", + "timeZone": "E. South America Standard Time" + }, + "brazilsoutheast": { + "abbreviation": "brse", + "recoveryServicesGeo": "bse", + "timeDifference": "-3:00", + "timeZone": "E. South America Standard Time" + }, + "canadacentral": { + "abbreviation": "cac", + "recoveryServicesGeo": "cnc", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "canadaeast": { + "abbreviation": "cae", + "recoveryServicesGeo": "cne", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "centralindia": { + "abbreviation": "inc", + "recoveryServicesGeo": "inc", + "timeDifference": "+5:30", + "timeZone": "India Standard Time" + }, + "centralus": { + "abbreviation": "usc", + "recoveryServicesGeo": "cus", + "timeDifference": "-6:00", + "timeZone": "Central Standard Time" + }, + "eastasia": { + "abbreviation": "ase", + "recoveryServicesGeo": "ea", + "timeDifference": "+8:00", + "timeZone": "China Standard Time" + }, + "eastus": { + "abbreviation": "use", + "recoveryServicesGeo": "eus", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "eastus2": { + "abbreviation": "use2", + "recoveryServicesGeo": "eus2", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "francecentral": { + "abbreviation": "frc", + "recoveryServicesGeo": "frc", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "francesouth": { + "abbreviation": "frs", + "recoveryServicesGeo": "frs", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "germanynorth": { + "abbreviation": "den", + "recoveryServicesGeo": "gn", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "germanywestcentral": { + "abbreviation": "dewc", + "recoveryServicesGeo": "gwc", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "israelcentral": { + "abbreviation": "ilc", + "recoveryServicesGeo": "ilc", + "timeDifference": "+2:00", + "timeZone": "Israel Standard Time" + }, + "italynorth": { + "abbreviation": "itn", + "recoveryServicesGeo": "itn", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "japaneast": { + "abbreviation": "jpe", + "recoveryServicesGeo": "jpe", + "timeDifference": "+9:00", + "timeZone": "Tokyo Standard Time" + }, + "japanwest": { + "abbreviation": "jpw", + "recoveryServicesGeo": "jpw", + "timeDifference": "+9:00", + "timeZone": "Tokyo Standard Time" + }, + "jioindiacentral": { + "abbreviation": "injc", + "recoveryServicesGeo": "jic", + "timeDifference": "+5:30", + "timeZone": "India Standard Time" + }, + "jioindiawest": { + "abbreviation": "injw", + "recoveryServicesGeo": "jiw", + "timeDifference": "+5:30", + "timeZone": "India Standard Time" + }, + "koreacentral": { + "abbreviation": "krc", + "recoveryServicesGeo": "krc", + "timeDifference": "+9:00", + "timeZone": "Korea Standard Time" + }, + "koreasouth": { + "abbreviation": "krs", + "recoveryServicesGeo": "krs", + "timeDifference": "+9:00", + "timeZone": "Korea Standard Time" + }, + "northcentralus": { + "abbreviation": "usnc", + "recoveryServicesGeo": "ncus", + "timeDifference": "-6:00", + "timeZone": "Central Standard Time" + }, + "northeurope": { + "abbreviation": "eun", + "recoveryServicesGeo": "ne", + "timeDifference": "0:00", + "timeZone": "GMT Standard Time" + }, + "norwayeast": { + "abbreviation": "noe", + "recoveryServicesGeo": "nwe", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "norwaywest": { + "abbreviation": "now", + "recoveryServicesGeo": "nww", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "polandcentral": { + "abbreviation": "plc", + "recoveryServicesGeo": "plc", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "qatarcentral": { + "abbreviation": "qac", + "recoveryServicesGeo": "qac", + "timeDifference": "+3:00", + "timeZone": "Arabian Standard Time" + }, + "southafricanorth": { + "abbreviation": "zan", + "recoveryServicesGeo": "san", + "timeDifference": "+2:00", + "timeZone": "South Africa Standard Time" + }, + "southafricawest": { + "abbreviation": "zaw", + "recoveryServicesGeo": "saw", + "timeDifference": "+2:00", + "timeZone": "South Africa Standard Time" + }, + "southcentralus": { + "abbreviation": "ussc", + "recoveryServicesGeo": "scus", + "timeDifference": "-6:00", + "timeZone": "Central Standard Time" + }, + "southeastasia": { + "abbreviation": "asse", + "recoveryServicesGeo": "sea", + "timeDifference": "+8:00", + "timeZone": "Singapore Standard Time" + }, + "southindia": { + "abbreviation": "ins", + "recoveryServicesGeo": "ins", + "timeDifference": "+5:30", + "timeZone": "India Standard Time" + }, + "swedencentral": { + "abbreviation": "sec", + "recoveryServicesGeo": "sdc", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "switzerlandnorth": { + "abbreviation": "chn", + "recoveryServicesGeo": "szn", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "switzerlandwest": { + "abbreviation": "chw", + "recoveryServicesGeo": "szw", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "uaecentral": { + "abbreviation": "aec", + "recoveryServicesGeo": "uac", + "timeDifference": "+3:00", + "timeZone": "Arabian Standard Time" + }, + "uaenorth": { + "abbreviation": "aen", + "recoveryServicesGeo": "uan", + "timeDifference": "+3:00", + "timeZone": "Arabian Standard Time" + }, + "uksouth": { + "abbreviation": "uks", + "recoveryServicesGeo": "uks", + "timeDifference": "0:00", + "timeZone": "GMT Standard Time" + }, + "ukwest": { + "abbreviation": "ukw", + "recoveryServicesGeo": "ukw", + "timeDifference": "0:00", + "timeZone": "GMT Standard Time" + }, + "westcentralus": { + "abbreviation": "uswc", + "recoveryServicesGeo": "wcus", + "timeDifference": "-7:00", + "timeZone": "Mountain Standard Time" + }, + "westeurope": { + "abbreviation": "euw", + "recoveryServicesGeo": "we", + "timeDifference": "+1:00", + "timeZone": "Central Europe Standard Time" + }, + "westindia": { + "abbreviation": "inw", + "recoveryServicesGeo": "inw", + "timeDifference": "+5:30", + "timeZone": "India Standard Time" + }, + "westus": { + "abbreviation": "usw", + "recoveryServicesGeo": "wus", + "timeDifference": "-8:00", + "timeZone": "Pacific Standard Time" + }, + "westus2": { + "abbreviation": "usw2", + "recoveryServicesGeo": "wus2", + "timeDifference": "-8:00", + "timeZone": "Pacific Standard Time" + }, + "westus3": { + "abbreviation": "usw3", + "recoveryServicesGeo": "wus3", + "timeDifference": "-7:00", + "timeZone": "Mountain Standard Time" + } + }, + "AzureUSGovernment": { + "usdodcentral": { + "abbreviation": "dodc", + "recoveryServicesGeo": "udc", + "timeDifference": "-6:00", + "timeZone": "Central Standard Time" + }, + "usdodeast": { + "abbreviation": "dode", + "recoveryServicesGeo": "ude", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "usgovarizona": { + "abbreviation": "az", + "recoveryServicesGeo": "uga", + "timeDifference": "-7:00", + "timeZone": "Mountain Standard Time" + }, + "usgovtexas": { + "abbreviation": "tx", + "recoveryServicesGeo": "ugt", + "timeDifference": "-6:00", + "timeZone": "Central Standard Time" + }, + "usgovvirginia": { + "abbreviation": "va", + "recoveryServicesGeo": "ugv", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + } + }, + "USNat": { + "usnateast": { + "abbreviation": "east", + "recoveryServicesGeo": "exe", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "usnatwest": { + "abbreviation": "west", + "recoveryServicesGeo": "exw", + "timeDifference": "-8:00", + "timeZone": "Pacific Standard Time" + } + }, + "USSec": { + "usseceast": { + "abbreviation": "east", + "recoveryServicesGeo": "rxe", + "timeDifference": "-5:00", + "timeZone": "Eastern Standard Time" + }, + "ussecwest": { + "abbreviation": "west", + "recoveryServicesGeo": "rxw", + "timeDifference": "-8:00", + "timeZone": "Pacific Standard Time" + } + } + }, + "$fxv#1": { + "actionGroups": "ag", + "applicationGroups": "vdag", + "applicationInsights": "appi", + "appServicePlans": "asp", + "automationAccounts": "aa", + "availabilitySets": "avail", + "azureFirewalls": "afw", + "bastionHosts": "bas", + "computeGallieries": "cg", + "dataCollectionEndpoints": "dce", + "dataCollectionRuleAssociations": "dcra", + "dataCollectionRules": "dcr", + "diagnosticSettings": "diag", + "diskAccesses": "da", + "diskEncryptionSets": "des", + "disks": "disk", + "firewallPolicies": "afwp", + "functionApps": "func", + "hostPools": "vdpool", + "ipConfigurations": "ipconf", + "keyVaults": "kv", + "logAnalyticsWorkspaces": "log", + "netAppAccounts": "naa", + "netAppCapacityPools": "nacp", + "networkInterfaces": "nic", + "networkSecurityGroups": "nsg", + "networkWatchers": "nw", + "privateEndpoints": "pe", + "privateLinkScopes": "pls", + "publicIPAddresses": "pip", + "recoveryServicesVaults": "rsv", + "remoteApplicationGroups": "vdag", + "resourceGroups": "rg", + "routeTables": "rt", + "scalingPlans": "vdscaling", + "storageAccounts": "st", + "subnets": "snet", + "userAssignedIdentities": "id", + "virtualMachines": "vm", + "virtualNetworks": "vnet", + "workspaces": "vdws" + }, + "locations": "[variables('$fxv#0')[environment().name]]", + "locationAbbreviation": "[variables('locations')[parameters('location')].abbreviation]", + "resourceAbbreviations": "[variables('$fxv#1')]", + "namingConvention": "[format('{0}-{1}{2}-{3}-{4}-{5}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", + "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", + "names": { + "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", + "applicationGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-desktop', variables('resourceAbbreviations').applicationGroups))]", + "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", + "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", + "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", + "automationAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", + "automationAccountNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", + "automationAccountPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').automationAccounts)]", + "availabilitySet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').availabilitySets)]", + "azureFirewall": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').azureFirewalls)]", + "azureFirewallClientPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, format('client-{0}', variables('resourceAbbreviations').azureFirewalls))]", + "azureFirewallClientPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-client-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').azureFirewalls))]", + "azureFirewallDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').azureFirewalls)]", + "azureFirewallManagementPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, format('mgmt-{0}', variables('resourceAbbreviations').azureFirewalls))]", + "azureFirewallManagementPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-mgmt-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').azureFirewalls))]", + "azureFirewallPolicy": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').firewallPolicies)]", + "bastionHost": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').bastionHosts)]", + "bastionHostNetworkSecurityGroup": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkSecurityGroups), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", + "bastionHostDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", + "bastionHostPublicIPAddress": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').publicIPAddresses), parameters('tokens').service, variables('resourceAbbreviations').bastionHosts)]", + "bastionHostPublicIPAddressDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').publicIPAddresses, variables('resourceAbbreviations').bastionHosts))]", + "computeGallery": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').computeGallieries), '-', '_')]", + "dataCollectionEndpoint": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionEndpoints)]", + "dataCollectionRuleAssociation": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionRuleAssociations)]", + "dataCollectionRule": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').dataCollectionRules)]", + "diskAccess": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').diskAccesses)]", + "diskAccessNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').diskAccesses)]", + "diskAccessPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').diskAccesses)]", + "diskEncryptionSet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').diskEncryptionSets)]", + "functionApp": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').functionApps)]", + "functionAppNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').functionApps, parameters('tokens').service))]", + "functionAppPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').functionApps, parameters('tokens').service))]", + "hostPool": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').hostPools)]", + "hostPoolDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", + "hostPoolNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", + "hostPoolPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').hostPools)]", + "keyVault": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').keyVaults), '-', ''), parameters('networkName'), parameters('networkShortName'))]", + "keyVaultDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", + "keyVaultNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", + "keyVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', variables('resourceAbbreviations').keyVaults, parameters('tokens').service))]", + "logAnalyticsWorkspace": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').logAnalyticsWorkspaces)]", + "logAnalyticsWorkspaceDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').logAnalyticsWorkspaces)]", + "netAppAccountCapacityPool": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').netAppCapacityPools)]", + "netAppAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').netAppAccounts)]", + "networkSecurityGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').networkSecurityGroups)]", + "networkSecurityGroupDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').networkSecurityGroups)]", + "networkWatcher": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').networkWatchers)]", + "privateLinkScope": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').privateLinkScopes)]", + "privateLinkScopeNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').privateLinkScopes)]", + "privateLinkScopePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').privateLinkScopes)]", + "recoveryServicesVault": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').recoveryServicesVaults)]", + "recoveryServicesVaultNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", + "recoveryServicesVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", + "resourceGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').resourceGroups)]", + "routeTable": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').routeTables)]", + "scalingPlan": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').scalingPlans)]", + "scalingPlanDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').scalingPlans)]", + "storageAccount": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').storageAccounts), parameters('networkName'), parameters('networkShortName'))]", + "storageAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').storageAccounts))]", + "storageAccountBlobNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountFileNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-file', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountQueueNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-queue', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountTableNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-table', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountBlobPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountFilePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-file', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountQueuePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-queue', variables('resourceAbbreviations').storageAccounts))]", + "storageAccountTablePrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-table', variables('resourceAbbreviations').storageAccounts))]", + "subnet": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').subnets)]", + "userAssignedIdentity": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').userAssignedIdentities)]", + "virtualMachine": "[replace(replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').virtualMachines), parameters('environmentAbbreviation'), first(parameters('environmentAbbreviation'))), parameters('networkName'), ''), '-', '')]", + "virtualMachineDisk": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').disks), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", + "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", + "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", + "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", + "workspaceFeed": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobal": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" + } + }, + "resources": [], + "outputs": { + "locations": { + "type": "object", + "value": "[variables('locations')]" + }, + "names": { + "type": "object", + "value": "[variables('names')]" + }, + "resourceAbbreviations": { + "type": "object", + "value": "[variables('resourceAbbreviations')]" + }, + "tokens": { + "type": "object", + "value": "[parameters('tokens')]" + } + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('private-dns-zones-{0}', parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "locations": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locations.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "17619606927129129347" + } + }, + "parameters": { + "locations": { + "type": "object" + } + }, + "variables": { + "copy": [ + { + "name": "privateDnsZoneNames_Backup", + "count": "[length(items(parameters('locations')))]", + "input": "[format('privatelink.{0}.backup.windowsazure.{1}', items(parameters('locations'))[copyIndex('privateDnsZoneNames_Backup')].value.recoveryServicesGeo, coalesce(variables('privateDnsZoneSuffixes_Backup')[environment().name], variables('cloudSuffix')))]" + } + ], + "cloudSuffix": "[replace(replace(environment().resourceManager, 'https://management.', ''), '/', '')]", + "privateDnsZoneNames": "[union(createArray(format('privatelink.agentsvc.azure-automation.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureAutomation')[environment().name], variables('cloudSuffix'))), format('privatelink.azure-automation.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureAutomation')[environment().name], variables('cloudSuffix'))), format('privatelink.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureWebSites')[environment().name], format('appservice.{0}', variables('cloudSuffix')))), format('scm.privatelink.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureWebSites')[environment().name], format('appservice.{0}', variables('cloudSuffix')))), format('privatelink.wvd.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureVirtualDesktop')[environment().name], variables('cloudSuffix'))), format('privatelink-global.wvd.{0}', coalesce(variables('privateDnsZoneSuffixes_AzureVirtualDesktop')[environment().name], variables('cloudSuffix'))), format('privatelink.file.{0}', environment().suffixes.storage), format('privatelink.queue.{0}', environment().suffixes.storage), format('privatelink.table.{0}', environment().suffixes.storage), format('privatelink.blob.{0}', environment().suffixes.storage), format('privatelink{0}', replace(environment().suffixes.keyvaultDns, 'vault', 'vaultcore')), format('privatelink.monitor.{0}', coalesce(variables('privateDnsZoneSuffixes_Monitor')[environment().name], variables('cloudSuffix'))), format('privatelink.ods.opinsights.{0}', coalesce(variables('privateDnsZoneSuffixes_Monitor')[environment().name], variables('cloudSuffix'))), format('privatelink.oms.opinsights.{0}', coalesce(variables('privateDnsZoneSuffixes_Monitor')[environment().name], variables('cloudSuffix')))), variables('privateDnsZoneNames_Backup'))]", + "privateDnsZoneSuffixes_AzureAutomation": { + "AzureCloud": "net", + "AzureUSGovernment": "us", + "USNat": null, + "USSec": null + }, + "privateDnsZoneSuffixes_AzureVirtualDesktop": { + "AzureCloud": "microsoft.com", + "AzureUSGovernment": "azure.us", + "USNat": null, + "USSec": null + }, + "privateDnsZoneSuffixes_AzureWebSites": { + "AzureCloud": "azurewebsites.net", + "AzureUSGovernment": "azurewebsites.us", + "USNat": null, + "USSec": null + }, + "privateDnsZoneSuffixes_Backup": { + "AzureCloud": "com", + "AzureUSGovernment": "us", + "USNat": null, + "USSec": null + }, + "privateDnsZoneSuffixes_Monitor": { + "AzureCloud": "azure.com", + "AzureUSGovernment": "azure.us", + "USNat": null, + "USSec": null + } + }, + "resources": [], + "outputs": { + "names": { + "type": "array", + "value": "[variables('privateDnsZoneNames')]" + } + } + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix')))]" + ] + } + ], + "outputs": { + "locationProperties": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locations.value[parameters('location')]]" + }, + "mlzTags": { + "type": "object", + "value": "[variables('mlzTags')]" + }, + "privateDnsZones": { + "type": "array", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('private-dns-zones-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value]" + }, + "resourceAbbreviations": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" + }, + "tiers": { + "type": "array", + "copy": { + "count": "[length(parameters('networks'))]", + "input": { + "name": "[parameters('networks')[copyIndex()].name]", + "shortName": "[parameters('networks')[copyIndex()].shortName]", + "deployUniqueResources": "[parameters('networks')[copyIndex()].deployUniqueResources]", + "subscriptionId": "[parameters('networks')[copyIndex()].subscriptionId]", + "nsgDiagLogs": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'nsgDiagLogs'), createArray())]", + "nsgDiagMetrics": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'nsgDiagMetrics'), createArray())]", + "nsgRules": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'nsgRules'), createArray())]", + "vnetAddressPrefix": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'vnetAddressPrefix'), '')]", + "vnetDiagLogs": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'vnetDiagLogs'), createArray())]", + "vnetDiagMetrics": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'vnetDiagMetrics'), createArray())]", + "subnetAddressPrefix": "[coalesce(tryGet(parameters('networks')[copyIndex()], 'subnetAddressPrefix'), '')]", + "namingConvention": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[copyIndex()].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value]" + } + } + }, + "tokens": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('naming-convention-{0}-{1}', parameters('networks')[0].shortName, parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value]" + } + } + } + } }, - "timeZone": { - "type": "string" + { + "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" + }, + "name": { + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'network')]" + }, + "tags": { + "value": "[parameters('tags')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "9371138343009436350" + } + }, + "parameters": { + "mlzTags": { + "type": "object" + }, + "name": { + "type": "string" + }, + "location": { + "type": "string" + }, + "tags": { + "type": "object", + "defaultValue": {} + } + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2019-05-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Resources/resourceGroups'), parameters('tags')['Microsoft.Resources/resourceGroups'], createObject()), parameters('mlzTags'))]" + } + ], + "outputs": { + "id": { + "type": "string", + "value": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name'))]" + }, + "name": { + "type": "string", + "value": "[parameters('name')]" + }, + "location": { + "type": "string", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name')), '2019-05-01', 'full').location]" + }, + "tags": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('name')), '2019-05-01', 'full').tags]" + } + } + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] }, - "virtualMachinePassword": { - "type": "securestring" + { + "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "additionalSubnets": { + "value": "[parameters('additionalSubnets')]" + }, + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "deployNetworkWatcher": { + "value": "[parameters('deployNetworkWatcher')]" + }, + "hubVirtualNetworkResourceId": { + "value": "[parameters('hubVirtualNetworkResourceId')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" + }, + "networkSecurityGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.networkSecurityGroup]" + }, + "networkSecurityGroupRules": { + "value": "[parameters('networkSecurityGroupRules')]" + }, + "networkWatcherName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.networkWatcher]" + }, + "resourceGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + }, + "routeTableName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.routeTable]" + }, + "routeTableRouteNextHopIpAddress": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('firewallResourceId'), '/')[2], split(parameters('firewallResourceId'), '/')[4]), 'Microsoft.Network/azureFirewalls', split(parameters('firewallResourceId'), '/')[8]), '2020-11-01').ipConfigurations[0].properties.privateIPAddress]" + }, + "subnetAddressPrefix": { + "value": "[parameters('subnetAddressPrefix')]" + }, + "subnetName": "[if(empty(parameters('subnetName')), createObject('value', reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.subnet), createObject('value', parameters('subnetName')))]", + "subscriptionId": { + "value": "[variables('subscriptionId')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "virtualNetworkAddressPrefix": { + "value": "[parameters('virtualNetworkAddressPrefix')]" + }, + "virtualNetworkName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention.virtualNetwork]" + }, + "vNetDnsServers": { + "value": "[coalesce(tryGet(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01'), 'dhcpOptions', 'dnsServers'), createArray())]" + }, + "workloadShortName": { + "value": "[parameters('workloadShortName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "12095518102496352105" + } + }, + "parameters": { + "additionalSubnets": { + "type": "array" + }, + "deploymentNameSuffix": { + "type": "string" + }, + "deployNetworkWatcher": { + "type": "bool" + }, + "hubVirtualNetworkResourceId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "networkSecurityGroupName": { + "type": "string" + }, + "networkSecurityGroupRules": { + "type": "array" + }, + "networkWatcherName": { + "type": "string" + }, + "resourceGroupName": { + "type": "string" + }, + "routeTableName": { + "type": "string" + }, + "routeTableRouteNextHopIpAddress": { + "type": "string" + }, + "subnetAddressPrefix": { + "type": "string" + }, + "subnetName": { + "type": "string" + }, + "subscriptionId": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "vNetDnsServers": { + "type": "array" + }, + "virtualNetworkAddressPrefix": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "workloadShortName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "additionalSubnets": { + "value": "[parameters('additionalSubnets')]" + }, + "deployNetworkWatcher": { + "value": "[parameters('deployNetworkWatcher')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "networkSecurityGroupName": { + "value": "[parameters('networkSecurityGroupName')]" + }, + "networkSecurityGroupRules": { + "value": "[parameters('networkSecurityGroupRules')]" + }, + "networkWatcherName": { + "value": "[parameters('networkWatcherName')]" + }, + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "routeTableName": { + "value": "[parameters('routeTableName')]" + }, + "routeTableRouteNextHopIpAddress": { + "value": "[parameters('routeTableRouteNextHopIpAddress')]" + }, + "subnetAddressPrefix": { + "value": "[parameters('subnetAddressPrefix')]" + }, + "subnetName": { + "value": "[parameters('subnetName')]" + }, + "subscriptionId": { + "value": "[parameters('subscriptionId')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "virtualNetworkAddressPrefix": { + "value": "[parameters('virtualNetworkAddressPrefix')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "vNetDnsServers": { + "value": "[parameters('vNetDnsServers')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "11818136489056939588" + } + }, + "parameters": { + "additionalSubnets": { + "type": "array", + "defaultValue": [] + }, + "deployNetworkWatcher": { + "type": "bool" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "networkSecurityGroupName": { + "type": "string" + }, + "networkSecurityGroupRules": { + "type": "array" + }, + "networkWatcherName": { + "type": "string" + }, + "resourceGroupName": { + "type": "string" + }, + "routeTableName": { + "type": "string" + }, + "routeTableRouteNextHopIpAddress": { + "type": "string" + }, + "subnetAddressPrefix": { + "type": "string" + }, + "subnetName": { + "type": "string" + }, + "subscriptionId": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "virtualNetworkAddressPrefix": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "vNetDnsServers": { + "type": "array" + } + }, + "variables": { + "delegations": { + "AzureNetAppFiles": [ + { + "name": "Microsoft.Netapp.volumes", + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets/delegations', parameters('virtualNetworkName'), 'AzureNetAppFiles', 'delegation')]", + "properties": { + "serviceName": "Microsoft.Netapp/volumes" + }, + "type": "Microsoft.Network/virtualNetworks/subnets/delegations" + } + ], + "FunctionAppOutbound": [ + { + "name": "Microsoft.Web/sites", + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets/delegations', parameters('virtualNetworkName'), 'FunctionAppOutbound', 'delegation')]", + "properties": { + "serviceName": "Microsoft.Web/serverfarms" + }, + "type": "Microsoft.Network/virtualNetworks/subnets/delegations" + } + ] + }, + "subnets": "[union(createArray(createObject('name', parameters('subnetName'), 'properties', createObject('addressPrefix', parameters('subnetAddressPrefix')))), parameters('additionalSubnets'))]" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "networkSecurityGroup", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "name": { + "value": "[parameters('networkSecurityGroupName')]" + }, + "securityRules": { + "value": "[parameters('networkSecurityGroupRules')]" + }, + "tags": { + "value": "[parameters('tags')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "3681943409502537301" + } + }, + "parameters": { + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "name": { + "type": "string" + }, + "securityRules": { + "type": "array" + }, + "tags": { + "type": "object" + } + }, + "resources": [ + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2021-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/networkSecurityGroups'), parameters('tags')['Microsoft.Network/networkSecurityGroups'], createObject()), parameters('mlzTags'))]", + "properties": { + "securityRules": "[parameters('securityRules')]" + } + } + ], + "outputs": { + "id": { + "type": "string", + "value": "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('name'))]" + }, + "name": { + "type": "string", + "value": "[parameters('name')]" + } + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "routeTable", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "disableBgpRoutePropagation": { + "value": true + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "name": { + "value": "[parameters('routeTableName')]" + }, + "routeNextHopIpAddress": { + "value": "[parameters('routeTableRouteNextHopIpAddress')]" + }, + "tags": { + "value": "[parameters('tags')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "18425321023142226965" + } + }, + "parameters": { + "disableBgpRoutePropagation": { + "type": "bool" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "name": { + "type": "string" + }, + "routeAddressPrefix": { + "type": "string", + "defaultValue": "0.0.0.0/0" + }, + "routeName": { + "type": "string", + "defaultValue": "default_route" + }, + "routeNextHopIpAddress": { + "type": "string" + }, + "routeNextHopType": { + "type": "string", + "defaultValue": "VirtualAppliance" + }, + "tags": { + "type": "object" + } + }, + "resources": [ + { + "type": "Microsoft.Network/routeTables", + "apiVersion": "2021-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/routeTables'), parameters('tags')['Microsoft.Network/routeTables'], createObject()), parameters('mlzTags'))]", + "properties": { + "disableBgpRoutePropagation": "[parameters('disableBgpRoutePropagation')]", + "routes": [ + { + "name": "[parameters('routeName')]", + "properties": { + "addressPrefix": "[parameters('routeAddressPrefix')]", + "nextHopIpAddress": "[parameters('routeNextHopIpAddress')]", + "nextHopType": "[parameters('routeNextHopType')]" + } + } + ] + } + } + ], + "outputs": { + "id": { + "type": "string", + "value": "[resourceId('Microsoft.Network/routeTables', parameters('name'))]" + }, + "name": { + "type": "string", + "value": "[parameters('name')]" + } + } + } + } + }, + { + "condition": "[parameters('deployNetworkWatcher')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "networkWatcher", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "name": { + "value": "[parameters('networkWatcherName')]" + }, + "tags": { + "value": "[parameters('tags')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "15002544166394392504" + } + }, + "parameters": { + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "object" + } + }, + "resources": [ + { + "type": "Microsoft.Network/networkWatchers", + "apiVersion": "2021-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/networkWatchers'), parameters('tags')['Microsoft.Network/networkWatchers'], createObject()), parameters('mlzTags'))]", + "properties": {} + } + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "virtualNetwork", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "addressPrefix": { + "value": "[parameters('virtualNetworkAddressPrefix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "name": { + "value": "[parameters('virtualNetworkName')]" + }, + "subnets": { + "copy": [ + { + "name": "value", + "count": "[length(variables('subnets'))]", + "input": "[createObject('name', variables('subnets')[copyIndex('value')].name, 'properties', createObject('addressPrefix', variables('subnets')[copyIndex('value')].properties.addressPrefix, 'delegations', coalesce(tryGet(variables('delegations'), variables('subnets')[copyIndex('value')].name), createArray()), 'networkSecurityGroup', createObject('id', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup'), '2022-09-01').outputs.id.value), 'routeTable', createObject('id', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'routeTable'), '2022-09-01').outputs.id.value), 'privateEndpointNetworkPolicies', 'Disabled', 'privateLinkServiceNetworkPolicies', 'Disabled'))]" + } + ] + }, + "tags": { + "value": "[parameters('tags')]" + }, + "vNetDnsServers": { + "value": "[parameters('vNetDnsServers')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "16817025486402215719" + } + }, + "parameters": { + "addressPrefix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "name": { + "type": "string" + }, + "subnets": { + "type": "array" + }, + "tags": { + "type": "object" + }, + "vNetDnsServers": { + "type": "array" + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2021-02-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/virtualNetworks'), parameters('tags')['Microsoft.Network/virtualNetworks'], createObject()), parameters('mlzTags'))]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('addressPrefix')]" + ] + }, + "subnets": "[parameters('subnets')]", + "dhcpOptions": "[if(empty(parameters('vNetDnsServers')), null(), createObject('dnsServers', parameters('vNetDnsServers')))]" + } + } + ], + "outputs": { + "addressPrefix": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Network/virtualNetworks', parameters('name')), '2021-02-01').addressSpace.addressPrefixes[0]]" + }, + "dnsServers": { + "type": "array", + "value": "[parameters('vNetDnsServers')]" + }, + "id": { + "type": "string", + "value": "[resourceId('Microsoft.Network/virtualNetworks', parameters('name'))]" + }, + "name": { + "type": "string", + "value": "[parameters('name')]" + }, + "subnets": { + "type": "array", + "value": "[reference(resourceId('Microsoft.Network/virtualNetworks', parameters('name')), '2021-02-01').subnets]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup')]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkWatcher')]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'routeTable')]" + ] + } + ], + "outputs": { + "networkSecurityGroupName": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup'), '2022-09-01').outputs.name.value]" + }, + "networkSecurityGroupResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'networkSecurityGroup'), '2022-09-01').outputs.id.value]" + }, + "subnets": { + "type": "array", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.subnets.value]" + }, + "virtualNetworkAddressPrefix": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.addressPrefix.value]" + }, + "virtualNetworkName": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.name.value]" + }, + "virtualNetworkResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('subscriptionId'), parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'virtualNetwork'), '2022-09-01').outputs.id.value]" + } + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-spoke-peering-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "hubVirtualNetworkResourceId": { + "value": "[parameters('hubVirtualNetworkResourceId')]" + }, + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + }, + "spokeShortName": { + "value": "[parameters('workloadShortName')]" + }, + "spokeVirtualNetworkName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" + }, + "subscriptionId": { + "value": "[parameters('subscriptionId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "10267893616110384815" + } + }, + "parameters": { + "deploymentNameSuffix": { + "type": "string" + }, + "hubVirtualNetworkResourceId": { + "type": "string" + }, + "resourceGroupName": { + "type": "string" + }, + "spokeShortName": { + "type": "string" + }, + "spokeVirtualNetworkName": { + "type": "string" + }, + "subscriptionId": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('peer-{0}-to-hub-{1}', parameters('spokeShortName'), parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "remoteVirtualNetworkResourceId": { + "value": "[parameters('hubVirtualNetworkResourceId')]" + }, + "virtualNetworkName": { + "value": "[parameters('spokeVirtualNetworkName')]" + }, + "virtualNetworkPeerName": { + "value": "[format('to-{0}', split(parameters('hubVirtualNetworkResourceId'), '/')[8])]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "5574526676512163672" + } + }, + "parameters": { + "remoteVirtualNetworkResourceId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "virtualNetworkPeerName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", + "apiVersion": "2021-02-01", + "name": "[format('{0}/{1}', parameters('virtualNetworkName'), parameters('virtualNetworkPeerName'))]", + "properties": { + "allowForwardedTraffic": true, + "remoteVirtualNetwork": { + "id": "[parameters('remoteVirtualNetworkResourceId')]" + } + } + } + ] + } + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-hub-peering-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "hubVirtualNetworkName": { + "value": "[split(parameters('hubVirtualNetworkResourceId'), '/')[8]]" + }, + "resourceGroupName": { + "value": "[split(parameters('hubVirtualNetworkResourceId'), '/')[4]]" + }, + "spokeShortName": { + "value": "[parameters('workloadShortName')]" + }, + "spokeVirtualNetworkResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkResourceId.value]" + }, + "subscriptionId": { + "value": "[split(parameters('hubVirtualNetworkResourceId'), '/')[2]]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "11553909803736438916" + } + }, + "parameters": { + "deploymentNameSuffix": { + "type": "string" + }, + "hubVirtualNetworkName": { + "type": "string" + }, + "resourceGroupName": { + "type": "string" + }, + "spokeShortName": { + "type": "string" + }, + "spokeVirtualNetworkResourceId": { + "type": "string" + }, + "subscriptionId": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('peer-hub-to-{0}-{1}', parameters('spokeShortName'), parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('subscriptionId')]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "remoteVirtualNetworkResourceId": { + "value": "[parameters('spokeVirtualNetworkResourceId')]" + }, + "virtualNetworkName": { + "value": "[parameters('hubVirtualNetworkName')]" + }, + "virtualNetworkPeerName": { + "value": "[format('to-{0}', split(parameters('spokeVirtualNetworkResourceId'), '/')[8])]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "5574526676512163672" + } + }, + "parameters": { + "remoteVirtualNetworkResourceId": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "virtualNetworkPeerName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", + "apiVersion": "2021-02-01", + "name": "[format('{0}/{1}', parameters('virtualNetworkName'), parameters('virtualNetworkPeerName'))]", + "properties": { + "allowForwardedTraffic": true, + "remoteVirtualNetwork": { + "id": "[parameters('remoteVirtualNetworkResourceId')]" + } + } + } + ] + } + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] + } + ], + "outputs": { + "networkSecurityGroupName": { + "type": "string", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.networkSecurityGroupName.value]" + }, + "subnets": { + "type": "array", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value]" + }, + "virtualNetworkName": { + "type": "string", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-spoke-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" + } + } + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] }, - "virtualMachineUsername": { - "type": "string" - } - }, - "variables": { - "hostPoolName": "[parameters('namingConvention').hostPool]", - "resourceGroups": "[union(createArray(parameters('resourceGroupControlPlane'), parameters('resourceGroupHosts'), parameters('resourceGroupManagement')), if(parameters('deployFslogix'), createArray(parameters('resourceGroupStorage')), createArray()))]", - "userAssignedIdentityNamePrefix": "[parameters('namingConvention').userAssignedIdentity]", - "virtualNetworkName": "[split(parameters('subnetResourceId'), '/')[8]]", - "virtualNetworkResourceGroupName": "[split(parameters('subnetResourceId'), '/')[4]]" - }, - "resources": [ { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(parameters('avdObjectId'), parameters('roleDefinitions').DesktopVirtualizationPowerOnOffContributor, subscription().id)]", + "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-vnet-links-{0}-sub-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "resourceGroup": "[variables('hubResourceGroupName')]", "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitions').DesktopVirtualizationPowerOnOffContributor)]", - "principalId": "[parameters('avdObjectId')]" - } + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "azureFirewallSku": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('firewallResourceId'), '/')[2], split(parameters('firewallResourceId'), '/')[4]), 'Microsoft.Network/azureFirewalls', split(parameters('firewallResourceId'), '/')[8]), '2020-11-01').sku.tier]" + }, + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "privateDnsZoneNames": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value]" + }, + "virtualNetworkName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" + }, + "virtualNetworkResourceGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + }, + "virtualNetworkSubscriptionId": { + "value": "[variables('subscriptionId')]" + }, + "workloadShortName": { + "value": "[parameters('workloadShortName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "4304275711041823961" + } + }, + "parameters": { + "azureFirewallSku": { + "type": "string" + }, + "deploymentNameSuffix": { + "type": "string" + }, + "privateDnsZoneNames": { + "type": "array" + }, + "virtualNetworkName": { + "type": "string" + }, + "virtualNetworkResourceGroupName": { + "type": "string" + }, + "virtualNetworkSubscriptionId": { + "type": "string" + }, + "workloadShortName": { + "type": "string" + } + }, + "resources": [ + { + "condition": "[equals(parameters('azureFirewallSku'), 'Basic')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-vnet-links-{0}-rg-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "privateDnsZoneNames": { + "value": "[parameters('privateDnsZoneNames')]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + }, + "virtualNetworkResourceGroupName": { + "value": "[parameters('virtualNetworkResourceGroupName')]" + }, + "virtualNetworkSubscriptionId": { + "value": "[parameters('virtualNetworkSubscriptionId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "16077950968688123011" + } + }, + "parameters": { + "privateDnsZoneNames": { + "type": "array" + }, + "virtualNetworkName": { + "type": "string" + }, + "virtualNetworkResourceGroupName": { + "type": "string" + }, + "virtualNetworkSubscriptionId": { + "type": "string" + } + }, + "resources": [ + { + "copy": { + "name": "virtualNetworkLinks", + "count": "[length(parameters('privateDnsZoneNames'))]" + }, + "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks", + "apiVersion": "2018-09-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneNames')[copyIndex()], parameters('virtualNetworkName'))]", + "location": "global", + "properties": { + "registrationEnabled": false, + "virtualNetwork": { + "id": "[resourceId(parameters('virtualNetworkSubscriptionId'), parameters('virtualNetworkResourceGroupName'), 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]" + } + } + } + ] + } + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] }, { + "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-disk-access-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", + "name": "[format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "hostPoolName": { - "value": "[variables('hostPoolName')]" + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "environmentAbbreviation": { + "value": "[parameters('environmentAbbreviation')]" + }, + "keyVaultPrivateDnsZoneResourceId": { + "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', replace(format('privatelink{0}', environment().suffixes.keyvaultDns), 'vault', 'vaultcore'))]" }, "location": { - "value": "[parameters('locationVirtualMachines')]" + "value": "[parameters('location')]" }, "mlzTags": { - "value": "[parameters('mlzTags')]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" }, - "namingConvention": { - "value": "[parameters('namingConvention')]" + "resourceAbbreviations": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" + "resourceGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" }, "subnetResourceId": { - "value": "[parameters('subnetResourceId')]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[0].id]" }, "tags": { "value": "[parameters('tags')]" + }, + "tier": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" + }, + "tokens": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value]" + }, + "workloadShortName": { + "value": "[parameters('workloadShortName')]" } }, "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5378203314803052603" + "version": "0.31.92.45157", + "templateHash": "12787329163785242553" } }, "parameters": { - "hostPoolName": { + "deploymentNameSuffix": { + "type": "string" + }, + "environmentAbbreviation": { + "type": "string" + }, + "keyVaultPrivateDnsZoneResourceId": { "type": "string" }, "location": { @@ -6752,10 +3654,10 @@ "mlzTags": { "type": "object" }, - "namingConvention": { + "resourceAbbreviations": { "type": "object" }, - "resourceGroupControlPlane": { + "resourceGroupName": { "type": "string" }, "subnetResourceId": { @@ -6763,133 +3665,468 @@ }, "tags": { "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.Compute/diskAccesses", - "apiVersion": "2021-04-01", - "name": "[parameters('namingConvention').diskAccess]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Compute/diskAccesses'), parameters('tags')['Microsoft.Compute/diskAccesses'], createObject()), parameters('mlzTags'))]", - "properties": {} }, + "tier": { + "type": "object" + }, + "tokens": { + "type": "object" + }, + "workloadShortName": { + "type": "string" + } + }, + "resources": [ { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[parameters('namingConvention').diskAccessPrivateEndpoint]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { - "customNetworkInterfaceName": "[parameters('namingConvention').diskAccessNetworkInterface]", - "privateLinkServiceConnections": [ - { - "name": "[parameters('namingConvention').diskAccessPrivateEndpoint]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.Compute/diskAccesses', parameters('namingConvention').diskAccess)]", - "groupIds": [ - "disks" + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "environmentAbbreviation": { + "value": "[parameters('environmentAbbreviation')]" + }, + "keyVaultPrivateDnsZoneResourceId": { + "value": "[parameters('keyVaultPrivateDnsZoneResourceId')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "resourceAbbreviations": { + "value": "[parameters('resourceAbbreviations')]" + }, + "subnetResourceId": { + "value": "[parameters('subnetResourceId')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "tier": { + "value": "[parameters('tier')]" + }, + "tokens": { + "value": "[parameters('tokens')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "11761568940379970751" + } + }, + "parameters": { + "diskEncryptionKeyExpirationInDays": { + "type": "int", + "defaultValue": 30 + }, + "environmentAbbreviation": { + "type": "string" + }, + "keyVaultPrivateDnsZoneResourceId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "resourceAbbreviations": { + "type": "object" + }, + "subnetResourceId": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "tier": { + "type": "object" + }, + "tokens": { + "type": "object" + } + }, + "variables": { + "keyVaultPrivateEndpointName": "[replace(parameters('tier').namingConvention.keyVaultPrivateEndpoint, parameters('tokens').service, 'cmk')]" + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id))]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.KeyVault/vaults'), parameters('tags')['Microsoft.KeyVault/vaults'], createObject()), parameters('mlzTags'))]", + "properties": { + "enabledForDeployment": false, + "enabledForDiskEncryption": false, + "enabledForTemplateDeployment": false, + "enablePurgeProtection": true, + "enableRbacAuthorization": true, + "enableSoftDelete": true, + "networkAcls": { + "bypass": "AzureServices", + "defaultAction": "Deny", + "ipRules": [], + "virtualNetworkRules": [] + }, + "publicNetworkAccess": "Disabled", + "sku": { + "family": "A", + "name": "premium" + }, + "softDeleteRetentionInDays": "[if(or(equals(parameters('environmentAbbreviation'), 'dev'), equals(parameters('environmentAbbreviation'), 'test')), 7, 90)]", + "tenantId": "[subscription().tenantId]" + } + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[variables('keyVaultPrivateEndpointName')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", + "properties": { + "customNetworkInterfaceName": "[replace(parameters('tier').namingConvention.keyVaultNetworkInterface, parameters('tokens').service, 'cmk')]", + "privateLinkServiceConnections": [ + { + "name": "[variables('keyVaultPrivateEndpointName')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]", + "groupIds": [ + "vault" + ] + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2021-08-01", + "name": "[format('{0}/{1}', variables('keyVaultPrivateEndpointName'), format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "ipconfig1", + "properties": { + "privateDnsZoneId": "[parameters('keyVaultPrivateDnsZoneResourceId')]" + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', variables('keyVaultPrivateEndpointName'))]", + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)), 'DiskEncryptionKey')]", + "properties": { + "attributes": { + "enabled": true + }, + "keySize": 4096, + "kty": "RSA", + "rotationPolicy": { + "attributes": { + "expiryTime": "[format('P{0}D', string(parameters('diskEncryptionKeyExpirationInDays')))]" + }, + "lifetimeActions": [ + { + "action": { + "type": "Notify" + }, + "trigger": { + "timeBeforeExpiry": "P10D" + } + }, + { + "action": { + "type": "Rotate" + }, + "trigger": { + "timeAfterCreate": "[format('P{0}D', string(sub(parameters('diskEncryptionKeyExpirationInDays'), 7)))]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)), 'StorageEncryptionKey')]", + "properties": { + "attributes": { + "enabled": true + }, + "keySize": 4096, + "kty": "RSA", + "rotationPolicy": { + "attributes": { + "expiryTime": "[format('P{0}D', string(parameters('diskEncryptionKeyExpirationInDays')))]" + }, + "lifetimeActions": [ + { + "action": { + "type": "Notify" + }, + "trigger": { + "timeBeforeExpiry": "P10D" + } + }, + { + "action": { + "type": "Rotate" + }, + "trigger": { + "timeAfterCreate": "[format('P{0}D', string(sub(parameters('diskEncryptionKeyExpirationInDays'), 7)))]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" ] } + ], + "outputs": { + "keyUriWithVersion": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults/keys', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)), 'DiskEncryptionKey'), '2022-07-01').keyUriWithVersion]" + }, + "keyVaultResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id)))]" + }, + "keyVaultName": { + "type": "string", + "value": "[format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id))]" + }, + "keyVaultUri": { + "type": "string", + "value": "[reference(resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('tier').namingConvention.keyVault, parameters('tokens').service, 'cmk'), resourceGroup().id))), '2022-07-01').vaultUri]" + }, + "storageKeyName": { + "type": "string", + "value": "StorageEncryptionKey" + } } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/diskAccesses', parameters('namingConvention').diskAccess)]" - ] - } - ], - "outputs": { - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.Compute/diskAccesses', parameters('namingConvention').diskAccess)]" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-policy-disks-{0}', parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "diskAccessResourceId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-disk-access-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - }, - "location": { - "value": "[parameters('locationVirtualMachines')]" - }, - "resourceGroupName": { - "value": "[parameters('resourceGroupHosts')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "702699492047562635" - } - }, - "parameters": { - "diskAccessResourceId": { - "type": "string", - "defaultValue": "" - }, - "location": { - "type": "string" + } }, - "resourceGroupName": { - "type": "string" - } - }, - "variables": { - "parameters": "[if(not(empty(parameters('diskAccessResourceId'))), createObject('diskAccessId', createObject('type', 'String', 'metadata', createObject('displayName', 'Disk Access Resource Id', 'description', 'The resource Id of the Disk Access to associate to the managed disks.'))), createObject())]", - "operations": "[if(not(empty(parameters('diskAccessResourceId'))), createArray(createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/networkAccessPolicy', 'value', 'AllowPrivate'), createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/publicNetworkAccess', 'value', 'Disabled'), createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/diskAccessId', 'value', '[parameters(''diskAccessId'')]')), createArray(createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/networkAccessPolicy', 'value', 'DenyAll'), createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/publicNetworkAccess', 'value', 'Disabled')))]" - }, - "resources": [ { - "type": "Microsoft.Authorization/policyDefinitions", - "apiVersion": "2021-06-01", - "name": "DiskNetworkAccess", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-des-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { - "description": "Disable network access to managed disks.", - "displayName": "Disable Disk Access", - "mode": "All", - "parameters": "[variables('parameters')]", - "policyRule": { - "if": { - "field": "type", - "equals": "Microsoft.Compute/disks" + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" }, - "then": { - "effect": "modify", - "details": { - "roleDefinitionIds": [ - "/providers/Microsoft.Authorization/roleDefinitions/60fc6e62-5479-42d4-8bf4-67625fcc2840" - ], - "operations": "[variables('operations')]" + "diskEncryptionSetName": { + "value": "[parameters('tier').namingConvention.diskEncryptionSet]" + }, + "keyUrl": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyUriWithVersion.value]" + }, + "keyVaultResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultResourceId.value]" + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "tags": "[if(contains(parameters('tags'), 'Microsoft.Compute/diskEncryptionSets'), createObject('value', parameters('tags')['Microsoft.Compute/diskEncryptionSets']), createObject('value', createObject()))]", + "workloadShortName": { + "value": "[parameters('workloadShortName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "4207798980384159491" + } + }, + "parameters": { + "deploymentNameSuffix": { + "type": "string" + }, + "diskEncryptionSetName": { + "type": "string" + }, + "keyUrl": { + "type": "string" + }, + "keyVaultResourceId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "tags": { + "type": "object" + }, + "workloadShortName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Compute/diskEncryptionSets", + "apiVersion": "2023-04-02", + "name": "[parameters('diskEncryptionSetName')]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Compute/diskEncryptionSets'), parameters('tags')['Microsoft.Compute/diskEncryptionSets'], createObject()), parameters('mlzTags'))]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "activeKey": { + "sourceVault": { + "id": "[parameters('keyVaultResourceId')]" + }, + "keyUrl": "[parameters('keyUrl')]" + }, + "encryptionType": "EncryptionAtRestWithPlatformAndCustomerKeys", + "rotationToLatestKeyVersionEnabled": true + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('assign-role-des-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "principalId": { + "value": "[reference(resourceId('Microsoft.Compute/diskEncryptionSets', parameters('diskEncryptionSetName')), '2023-04-02', 'full').identity.principalId]" + }, + "principalType": { + "value": "ServicePrincipal" + }, + "roleDefinitionId": { + "value": "[resourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]" + }, + "targetResourceId": { + "value": "[resourceGroup().id]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "1966035938992047983" + } + }, + "parameters": { + "targetResourceId": { + "type": "string" + }, + "roleDefinitionId": { + "type": "string" + }, + "principalId": { + "type": "string" + }, + "principalType": { + "type": "string", + "defaultValue": "ServicePrincipal", + "allowedValues": [ + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ] + }, + "description": { + "type": "string", + "defaultValue": "" + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(parameters('targetResourceId'), parameters('roleDefinitionId'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "principalType": "[parameters('principalType')]", + "roleDefinitionId": "[parameters('roleDefinitionId')]", + "description": "[parameters('description')]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/diskEncryptionSets', parameters('diskEncryptionSetName'))]" + ] + } + ], + "outputs": { + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Compute/diskEncryptionSets', parameters('diskEncryptionSetName'))]" } } - }, - "policyType": "Custom" - } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] }, { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "assign-policy-disk-network-access", + "name": "[format('deploy-id-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { @@ -6897,20 +4134,20 @@ }, "mode": "Incremental", "parameters": { - "diskAccessResourceId": { - "value": "[parameters('diskAccessResourceId')]" + "keyVaultName": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultName.value]" }, "location": { "value": "[parameters('location')]" }, - "policyDefinitionId": { - "value": "[subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess')]" + "mlzTags": { + "value": "[parameters('mlzTags')]" }, - "policyDisplayName": { - "value": "[reference(subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess'), '2021-06-01').displayName]" + "tags": { + "value": "[parameters('tags')]" }, - "policyName": { - "value": "[reference(subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess'), '2021-06-01').displayName]" + "userAssignedIdentityName": { + "value": "[replace(parameters('tier').namingConvention.userAssignedIdentity, format('-{0}', parameters('tokens').service), '')]" } }, "template": { @@ -6919,359 +4156,179 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6289202887333913438" + "version": "0.31.92.45157", + "templateHash": "7930493629995578222" } }, "parameters": { - "diskAccessResourceId": { + "keyVaultName": { "type": "string" }, "location": { "type": "string" }, - "policyDefinitionId": { - "type": "string" + "mlzTags": { + "type": "object" }, - "policyDisplayName": { - "type": "string" + "tags": { + "type": "object" }, - "policyName": { + "userAssignedIdentityName": { "type": "string" } }, "resources": [ { - "type": "Microsoft.Authorization/policyAssignments", - "apiVersion": "2022-06-01", - "name": "[parameters('policyName')]", + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2018-11-30", + "name": "[parameters('userAssignedIdentityName')]", "location": "[parameters('location')]", - "identity": { - "type": "SystemAssigned" - }, + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.ManagedIdentity/userAssignedIdentities'), parameters('tags')['Microsoft.ManagedIdentity/userAssignedIdentities'], createObject()), parameters('mlzTags'))]" + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('keyVaultName'))]", + "name": "[guid(parameters('userAssignedIdentityName'), 'e147488a-f6f5-4113-8e2d-b22465e65bf6', parameters('keyVaultName'))]", "properties": { - "displayName": "[parameters('policyDisplayName')]", - "policyDefinitionId": "[parameters('policyDefinitionId')]", - "parameters": "[if(not(empty(parameters('diskAccessResourceId'))), createObject('diskAccessId', createObject('value', parameters('diskAccessResourceId'))), createObject())]" - } + "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName')), '2018-11-30').principalId]", + "principalType": "ServicePrincipal", + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]" + ] } - ] + ], + "outputs": { + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('userAssignedIdentityName'))]" + } + } } }, "dependsOn": [ - "[subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess')]" + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" ] } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-disk-access-{0}', parameters('deploymentNameSuffix')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "location": { - "value": "[parameters('locationVirtualMachines')]" - }, - "name": { - "value": "[replace(variables('userAssignedIdentityNamePrefix'), parameters('serviceToken'), 'deployment')]" - }, - "tags": { - "value": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), variables('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.ManagedIdentity/userAssignedIdentities'), parameters('tags')['Microsoft.ManagedIdentity/userAssignedIdentities'], createObject()), parameters('mlzTags'))]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "12664463677760204409" - } - }, - "parameters": { - "location": { - "type": "string" - }, - "name": { - "type": "string" - }, - "tags": { - "type": "object" - } - }, - "resources": [ - { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2018-11-30", - "name": "[parameters('name')]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]" - } ], "outputs": { - "clientId": { + "diskEncryptionSetResourceId": { "type": "string", - "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')), '2018-11-30').clientId]" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-des-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" }, - "resourceId": { + "keyVaultName": { "type": "string", - "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name'))]" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultName.value]" }, - "principalId": { + "keyVaultUri": { "type": "string", - "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')), '2018-11-30').principalId]" - } - } - } - } - }, - { - "copy": { - "name": "roleAssignments_deployment", - "count": "[length(range(0, length(variables('resourceGroups'))))]" - }, - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-role-assignment-{0}-{1}', range(0, length(variables('resourceGroups')))[copyIndex()], parameters('deploymentNameSuffix'))]", - "resourceGroup": "[variables('resourceGroups')[range(0, length(variables('resourceGroups')))[copyIndex()]]]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "principalId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" - }, - "principalType": { - "value": "ServicePrincipal" - }, - "roleDefinitionId": { - "value": "acdd72a7-3385-48ef-bd42-f606fba81ae7" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1315528727979495191" - } - }, - "parameters": { - "principalId": { - "type": "string" - }, - "principalType": { - "type": "string" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value]" }, - "roleDefinitionId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", - "principalId": "[parameters('principalId')]", - "principalType": "[parameters('principalType')]" - } - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-role-assignment-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupStorage')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "principalId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" - }, - "principalType": { - "value": "ServicePrincipal" - }, - "roleDefinitionId": { - "value": "17d1049b-9a84-46fb-8f53-869881c3d3ab" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1315528727979495191" - } - }, - "parameters": { - "principalId": { - "type": "string" + "keyVaultResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultResourceId.value]" }, - "principalType": { - "type": "string" + "storageKeyName": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-kv-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageKeyName.value]" }, - "roleDefinitionId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", - "principalId": "[parameters('principalId')]", - "principalType": "[parameters('principalType')]" - } + "userAssignedIdentityResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('tier').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" } - ] + } } }, "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix')))]" + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" ] }, { + "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", + "name": "[format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "deploymentUserAssignedIdentityPrincipalId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" - }, - "deploymentUserAssignedIdentityResourceId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - }, - "diskEncryptionSetResourceId": { - "value": "[parameters('diskEncryptionSetResourceId')]" + "blobsPrivateDnsZoneResourceId": { + "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.blob.{0}', environment().suffixes.storage))]" }, - "diskName": { - "value": "[replace(parameters('namingConvention').virtualMachineDisk, parameters('serviceToken'), 'mgt')]" + "filesPrivateDnsZoneResourceId": { + "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.file.{0}', environment().suffixes.storage))]" }, - "diskSku": { - "value": "[parameters('diskSku')]" + "keyVaultUri": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value]" }, - "domainJoinPassword": { - "value": "[parameters('domainJoinPassword')]" + "location": { + "value": "[parameters('location')]" }, - "domainJoinUserPrincipalName": { - "value": "[parameters('domainJoinUserPrincipalName')]" + "logStorageSkuName": { + "value": "[parameters('logStorageSkuName')]" }, - "domainName": { - "value": "[parameters('domainName')]" + "mlzTags": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" }, - "hostPoolName": { - "value": "[variables('hostPoolName')]" + "network": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" }, - "location": { - "value": "[parameters('locationVirtualMachines')]" + "queuesPrivateDnsZoneResourceId": { + "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.queue.{0}', environment().suffixes.storage))]" }, - "mlzTags": { - "value": "[parameters('mlzTags')]" + "resourceGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" }, - "networkInterfaceName": { - "value": "[replace(parameters('namingConvention').virtualMachineNetworkInterface, parameters('serviceToken'), 'mgt')]" + "serviceToken": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" }, - "organizationalUnitPath": { - "value": "[parameters('organizationalUnitPath')]" + "storageEncryptionKeyName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageKeyName.value]" }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" + "subnetResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[0].id]" }, - "subnet": { - "value": "[split(parameters('subnetResourceId'), '/')[10]]" + "tablesPrivateDnsZoneResourceId": { + "value": "[resourceId(variables('hubSubscriptionId'), variables('hubResourceGroupName'), 'Microsoft.Network/privateDnsZones', format('privatelink.table.{0}', environment().suffixes.storage))]" }, "tags": { "value": "[parameters('tags')]" }, - "virtualMachineName": { - "value": "[replace(parameters('namingConvention').virtualMachine, parameters('serviceToken'), 'mgt')]" - }, - "virtualMachinePassword": { - "value": "[parameters('virtualMachinePassword')]" - }, - "virtualMachineUsername": { - "value": "[parameters('virtualMachineUsername')]" - }, - "virtualNetwork": { - "value": "[variables('virtualNetworkName')]" + "tier": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" }, - "virtualNetworkResourceGroup": { - "value": "[variables('virtualNetworkResourceGroupName')]" + "userAssignedIdentityResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.userAssignedIdentityResourceId.value]" } }, "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "16276650963509010370" + "version": "0.31.92.45157", + "templateHash": "17358288344184718166" } }, "parameters": { - "deploymentUserAssignedIdentityPrincipalId": { - "type": "string" - }, - "deploymentUserAssignedIdentityResourceId": { - "type": "string" - }, - "diskEncryptionSetResourceId": { - "type": "string" - }, - "diskName": { - "type": "string" - }, - "diskSku": { + "blobsPrivateDnsZoneResourceId": { "type": "string" }, - "domainJoinPassword": { - "type": "securestring" - }, - "domainJoinUserPrincipalName": { + "filesPrivateDnsZoneResourceId": { "type": "string" }, - "domainName": { + "keyVaultUri": { "type": "string" }, - "hostPoolName": { + "logStorageSkuName": { "type": "string" }, "location": { @@ -7280,504 +4337,837 @@ "mlzTags": { "type": "object" }, - "networkInterfaceName": { - "type": "string" + "network": { + "type": "object" }, - "organizationalUnitPath": { + "queuesPrivateDnsZoneResourceId": { "type": "string" }, - "resourceGroupControlPlane": { + "resourceGroupName": { "type": "string" }, - "subnet": { + "serviceToken": { "type": "string" }, - "tags": { - "type": "object" - }, - "timestamp": { - "type": "string", - "defaultValue": "[utcNow('yyyyMMddhhmmss')]" - }, - "virtualNetwork": { + "storageEncryptionKeyName": { "type": "string" }, - "virtualNetworkResourceGroup": { + "subnetResourceId": { "type": "string" }, - "virtualMachineName": { + "tablesPrivateDnsZoneResourceId": { "type": "string" }, - "virtualMachinePassword": { - "type": "securestring" + "tags": { + "type": "object" }, - "virtualMachineUsername": { + "tier": { + "type": "object" + }, + "userAssignedIdentityResourceId": { "type": "string" } }, - "variables": { - "tagsVirtualMachines": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Compute/virtualMachines'), parameters('tags')['Microsoft.Compute/virtualMachines'], createObject()), parameters('mlzTags'))]" - }, "resources": [ { - "type": "Microsoft.Network/networkInterfaces", - "apiVersion": "2020-05-01", - "name": "[parameters('networkInterfaceName')]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Network/networkInterfaces'), parameters('tags')['Microsoft.Network/networkInterfaces'], createObject()), parameters('mlzTags'))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "storage", + "subscriptionId": "[parameters('network').subscriptionId]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { - "ipConfigurations": [ - { - "name": "ipconfig", - "properties": { - "privateIPAllocationMethod": "Dynamic", - "subnet": { - "id": "[resourceId(parameters('virtualNetworkResourceGroup'), 'Microsoft.Network/virtualNetworks/subnets', parameters('virtualNetwork'), parameters('subnet'))]" - }, - "primary": true, - "privateIPAddressVersion": "IPv4" - } + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "blobsPrivateDnsZoneResourceId": { + "value": "[parameters('blobsPrivateDnsZoneResourceId')]" + }, + "filesPrivateDnsZoneResourceId": { + "value": "[parameters('filesPrivateDnsZoneResourceId')]" + }, + "keyVaultUri": { + "value": "[parameters('keyVaultUri')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "queuesPrivateDnsZoneResourceId": { + "value": "[parameters('queuesPrivateDnsZoneResourceId')]" + }, + "serviceToken": { + "value": "[parameters('serviceToken')]" + }, + "skuName": { + "value": "[parameters('logStorageSkuName')]" + }, + "storageEncryptionKeyName": { + "value": "[parameters('storageEncryptionKeyName')]" + }, + "subnetResourceId": { + "value": "[parameters('subnetResourceId')]" + }, + "tablesPrivateDnsZoneResourceId": { + "value": "[parameters('tablesPrivateDnsZoneResourceId')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "tier": { + "value": "[parameters('tier')]" + }, + "userAssignedIdentityResourceId": { + "value": "[parameters('userAssignedIdentityResourceId')]" } - ], - "enableAcceleratedNetworking": false, - "enableIPForwarding": false - } - }, - { - "type": "Microsoft.Compute/virtualMachines", - "apiVersion": "2021-11-01", - "name": "[parameters('virtualMachineName')]", - "location": "[parameters('location')]", - "tags": "[variables('tagsVirtualMachines')]", - "properties": { - "hardwareProfile": { - "vmSize": "Standard_B2s" }, - "storageProfile": { - "imageReference": { - "publisher": "MicrosoftWindowsServer", - "offer": "WindowsServer", - "sku": "2019-datacenter-core-g2", - "version": "latest" + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "1625826941635729014" + } }, - "osDisk": { - "deleteOption": "Delete", - "osType": "Windows", - "createOption": "FromImage", - "caching": "None", - "managedDisk": { - "diskEncryptionSet": { - "id": "[parameters('diskEncryptionSetResourceId')]" - }, - "storageAccountType": "[parameters('diskSku')]" + "parameters": { + "blobsPrivateDnsZoneResourceId": { + "type": "string" + }, + "filesPrivateDnsZoneResourceId": { + "type": "string" + }, + "keyVaultUri": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "queuesPrivateDnsZoneResourceId": { + "type": "string" + }, + "serviceToken": { + "type": "string" }, - "name": "[parameters('diskName')]" + "skuName": { + "type": "string" + }, + "storageEncryptionKeyName": { + "type": "string" + }, + "subnetResourceId": { + "type": "string" + }, + "tablesPrivateDnsZoneResourceId": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "tier": { + "type": "object" + }, + "userAssignedIdentityResourceId": { + "type": "string" + } }, - "dataDisks": [] - }, - "osProfile": { - "computerName": "[parameters('virtualMachineName')]", - "adminUsername": "[parameters('virtualMachineUsername')]", - "adminPassword": "[parameters('virtualMachinePassword')]", - "windowsConfiguration": { - "provisionVMAgent": true, - "enableAutomaticUpdates": false + "variables": { + "subResources": [ + { + "id": "[parameters('blobsPrivateDnsZoneResourceId')]", + "nic": "[parameters('tier').namingConvention.storageAccountBlobNetworkInterface]", + "pe": "[parameters('tier').namingConvention.storageAccountBlobPrivateEndpoint]" + }, + { + "id": "[parameters('filesPrivateDnsZoneResourceId')]", + "nic": "[parameters('tier').namingConvention.storageAccountFileNetworkInterface]", + "pe": "[parameters('tier').namingConvention.storageAccountFilePrivateEndpoint]" + }, + { + "id": "[parameters('queuesPrivateDnsZoneResourceId')]", + "nic": "[parameters('tier').namingConvention.storageAccountQueueNetworkInterface]", + "pe": "[parameters('tier').namingConvention.storageAccountQueuePrivateEndpoint]" + }, + { + "id": "[parameters('tablesPrivateDnsZoneResourceId')]", + "nic": "[parameters('tier').namingConvention.storageAccountTableNetworkInterface]", + "pe": "[parameters('tier').namingConvention.storageAccountTablePrivateEndpoint]" + } + ] }, - "secrets": [], - "allowExtensionOperations": true - }, - "networkProfile": { - "networkInterfaces": [ + "resources": [ { - "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2023-01-01", + "name": "[uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id)]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Storage/storageAccounts'), parameters('tags')['Microsoft.Storage/storageAccounts'], createObject()), parameters('mlzTags'))]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', parameters('userAssignedIdentityResourceId'))]": {} + } + }, + "kind": "StorageV2", + "sku": { + "name": "[parameters('skuName')]" + }, "properties": { - "deleteOption": "Delete" + "accessTier": "Hot", + "allowBlobPublicAccess": false, + "allowCrossTenantReplication": false, + "allowedCopyScope": "PrivateLink", + "allowSharedKeyAccess": false, + "defaultToOAuthAuthentication": false, + "dnsEndpointType": "Standard", + "encryption": { + "identity": { + "userAssignedIdentity": "[parameters('userAssignedIdentityResourceId')]" + }, + "keySource": "Microsoft.KeyVault", + "keyvaultproperties": { + "keyvaulturi": "[parameters('keyVaultUri')]", + "keyname": "[parameters('storageEncryptionKeyName')]" + }, + "requireInfrastructureEncryption": true, + "services": { + "blob": { + "keyType": "Account", + "enabled": true + }, + "file": { + "keyType": "Account", + "enabled": true + }, + "queue": { + "keyType": "Account", + "enabled": true + }, + "table": { + "keyType": "Account", + "enabled": true + } + } + }, + "minimumTlsVersion": "TLS1_2", + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Deny" + }, + "publicNetworkAccess": "Disabled", + "supportsHttpsTrafficOnly": true } - } - ] - }, - "securityProfile": { - "uefiSettings": { - "secureBootEnabled": true, - "vTpmEnabled": true - }, - "securityType": "TrustedLaunch", - "encryptionAtHost": true - }, - "diagnosticsProfile": { - "bootDiagnostics": { - "enabled": false - } - }, - "licenseType": "Windows_Server" - }, - "identity": { - "type": "SystemAssigned, UserAssigned", - "userAssignedIdentities": { - "[format('{0}', parameters('deploymentUserAssignedIdentityResourceId'))]": {} - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2021-03-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), 'IaaSAntimalware')]", - "location": "[parameters('location')]", - "tags": "[variables('tagsVirtualMachines')]", - "properties": { - "publisher": "Microsoft.Azure.Security", - "type": "IaaSAntimalware", - "typeHandlerVersion": "1.3", - "autoUpgradeMinorVersion": true, - "enableAutomaticUpgrade": false, - "settings": { - "AntimalwareEnabled": true, - "RealtimeProtectionEnabled": "true", - "ScheduledScanSettings": { - "isEnabled": "true", - "day": "7", - "time": "120", - "scanType": "Quick" - }, - "Exclusions": {} - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2021-03-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), 'GuestAttestation')]", - "location": "[parameters('location')]", - "properties": { - "publisher": "Microsoft.Azure.Security.WindowsAttestation", - "type": "GuestAttestation", - "typeHandlerVersion": "1.0", - "autoUpgradeMinorVersion": true, - "settings": { - "AttestationConfig": { - "MaaSettings": { - "maaEndpoint": "", - "maaTenantName": "GuestAttestation" }, - "AscSettings": { - "ascReportingEndpoint": "", - "ascReportingFrequency": "" + { + "copy": { + "name": "privateEndpoints", + "count": "[length(variables('subResources'))]" + }, + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[variables('subResources')[copyIndex()].pe]", + "location": "[parameters('location')]", + "tags": "[union(if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", + "properties": { + "customNetworkInterfaceName": "[variables('subResources')[copyIndex()].nic]", + "privateLinkServiceConnections": [ + { + "name": "[variables('subResources')[copyIndex()].pe]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]", + "groupIds": [ + "[split(split(variables('subResources')[copyIndex()].id, '/')[8], '.')[1]]" + ] + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]" + ] }, - "useCustomToken": "false", - "disableAlerts": "false" + { + "copy": { + "name": "privateDnsZoneGroups", + "count": "[length(variables('subResources'))]" + }, + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2021-08-01", + "name": "[format('{0}/{1}', variables('subResources')[copyIndex()].pe, uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "ipconfig1", + "properties": { + "privateDnsZoneId": "[variables('subResources')[copyIndex()].id]" + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', variables('subResources')[copyIndex()].pe)]", + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]" + ] + } + ], + "outputs": { + "id": { + "type": "string", + "value": "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('tier').namingConvention.storageAccount, parameters('serviceToken'), 'log'), resourceGroup().id))]" + } } } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" - ] - }, - { - "type": "Microsoft.Compute/virtualMachines/extensions", - "apiVersion": "2019-07-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), 'JsonADDomainExtension')]", - "location": "[parameters('location')]", - "tags": "[variables('tagsVirtualMachines')]", - "properties": { - "forceUpdateTag": "[parameters('timestamp')]", - "publisher": "Microsoft.Compute", - "type": "JsonADDomainExtension", - "typeHandlerVersion": "1.3", - "autoUpgradeMinorVersion": true, - "settings": { - "Name": "[parameters('domainName')]", - "Options": "3", - "OUPath": "[parameters('organizationalUnitPath')]", - "Restart": "true", - "User": "[parameters('domainJoinUserPrincipalName')]" - }, - "protectedSettings": { - "Password": "[parameters('domainJoinPassword')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('virtualMachineName'))]", - "name": "[guid(parameters('deploymentUserAssignedIdentityPrincipalId'), 'a959dbd1-f747-45e3-8ba6-dd80f235f97c', resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName')))]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", - "principalId": "[parameters('deploymentUserAssignedIdentityPrincipalId')]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" - ] + } } ], "outputs": { - "name": { - "type": "string", - "value": "[parameters('virtualMachineName')]" - }, - "resourceId": { + "storageAccountResourceId": { "type": "string", - "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', parameters('network').subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', 'storage'), '2022-09-01').outputs.id.value]" } } } }, "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix')))]" + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" ] }, { - "condition": "[or(parameters('enableApplicationInsights'), parameters('enableAvdInsights'))]", + "condition": "[not(empty(parameters('virtualNetworkAddressPrefix')))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", + "name": "[format('deploy-diag-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "deployActivityLogDiagnosticSetting": { + "value": "[parameters('deployActivityLogDiagnosticSetting')]" + }, "deploymentNameSuffix": { "value": "[parameters('deploymentNameSuffix')]" }, - "enableAvdInsights": { - "value": "[parameters('enableAvdInsights')]" + "keyVaultDiagnosticLogs": { + "value": "[parameters('keyVaultDiagnosticsLogs')]" }, - "hostPoolName": { - "value": "[variables('hostPoolName')]" + "keyVaultName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultName.value]" }, - "location": { - "value": "[parameters('locationVirtualMachines')]" + "logAnalyticsWorkspaceResourceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" }, - "logAnalyticsWorkspaceRetention": { - "value": "[parameters('logAnalyticsWorkspaceRetention')]" + "networkSecurityGroupDiagnosticsLogs": { + "value": "[parameters('networkSecurityGroupDiagnosticsLogs')]" }, - "logAnalyticsWorkspaceSku": { - "value": "[parameters('logAnalyticsWorkspaceSku')]" + "networkSecurityGroupDiagnosticsMetrics": { + "value": "[parameters('networkSecurityGroupDiagnosticsMetrics')]" }, - "mlzTags": { - "value": "[parameters('mlzTags')]" + "networkSecurityGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.networkSecurityGroupName.value]" }, - "namingConvention": { - "value": "[parameters('namingConvention')]" + "resourceGroupName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" }, - "privateLinkScopeResourceId": { - "value": "[parameters('privateLinkScopeResourceId')]" + "serviceToken": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" + "storageAccountResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageAccountResourceId.value]" }, - "serviceToken": { - "value": "[parameters('serviceToken')]" + "tier": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" }, - "tags": { - "value": "[parameters('tags')]" + "virtualNetworkDiagnosticsLogs": { + "value": "[parameters('virtualNetworkDiagnosticsLogs')]" + }, + "virtualNetworkDiagnosticsMetrics": { + "value": "[parameters('virtualNetworkDiagnosticsMetrics')]" + }, + "virtualNetworkName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualNetworkName.value]" } }, "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "12055090228824682687" + "version": "0.31.92.45157", + "templateHash": "4345251511078445463" } }, "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "enableAvdInsights": { + "deployActivityLogDiagnosticSetting": { "type": "bool" }, - "hostPoolName": { + "deploymentNameSuffix": { "type": "string" }, - "location": { - "type": "string" + "keyVaultDiagnosticLogs": { + "type": "array" }, - "logAnalyticsWorkspaceRetention": { - "type": "int" + "keyVaultName": { + "type": "string" }, - "logAnalyticsWorkspaceSku": { + "logAnalyticsWorkspaceResourceId": { "type": "string" }, - "mlzTags": { - "type": "object" + "networkSecurityGroupDiagnosticsLogs": { + "type": "array" }, - "namingConvention": { - "type": "object" + "networkSecurityGroupDiagnosticsMetrics": { + "type": "array" }, - "privateLinkScopeResourceId": { + "networkSecurityGroupName": { "type": "string" }, - "resourceGroupControlPlane": { + "resourceGroupName": { "type": "string" }, - "service": { - "type": "string", - "defaultValue": "mgmt" - }, "serviceToken": { "type": "string" }, - "tags": { + "storageAccountResourceId": { + "type": "string" + }, + "tier": { "type": "object" + }, + "virtualNetworkDiagnosticsLogs": { + "type": "array" + }, + "virtualNetworkDiagnosticsMetrics": { + "type": "array" + }, + "virtualNetworkName": { + "type": "string" } }, "resources": [ { - "type": "Microsoft.OperationalInsights/workspaces", - "apiVersion": "2021-06-01", - "name": "[replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service'))]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.OperationalInsights/workspaces'), parameters('tags')['Microsoft.OperationalInsights/workspaces'], createObject()), parameters('mlzTags'))]", + "condition": "[parameters('deployActivityLogDiagnosticSetting')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-activity-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", + "location": "[deployment().location]", "properties": { - "sku": { - "name": "[parameters('logAnalyticsWorkspaceSku')]" + "expressionEvaluationOptions": { + "scope": "inner" }, - "retentionInDays": "[parameters('logAnalyticsWorkspaceRetention')]", - "workspaceCapping": { - "dailyQuotaGb": -1 + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "4687229436121899773" + } + }, + "parameters": { + "logAnalyticsWorkspaceId": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2017-05-01-preview", + "name": "[format('diag-activity-log-{0}', subscription().subscriptionId)]", + "properties": { + "workspaceId": "[parameters('logAnalyticsWorkspaceId')]", + "logs": [ + { + "category": "Administrative", + "enabled": true + }, + { + "category": "Security", + "enabled": true + }, + { + "category": "ServiceHealth", + "enabled": true + }, + { + "category": "Alert", + "enabled": true + }, + { + "category": "Recommendation", + "enabled": true + }, + { + "category": "Policy", + "enabled": true + }, + { + "category": "Autoscale", + "enabled": true + }, + { + "category": "ResourceHealth", + "enabled": true + } + ] + } + } + ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-kv-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" }, - "publicNetworkAccessForIngestion": "Disabled", - "publicNetworkAccessForQuery": "Enabled" + "mode": "Incremental", + "parameters": { + "keyVaultDiagnosticSettingName": { + "value": "[replace(parameters('tier').namingConvention.keyVaultDiagnosticSetting, format('{0}-', parameters('serviceToken')), '')]" + }, + "keyVaultName": { + "value": "[parameters('keyVaultName')]" + }, + "keyVaultStorageAccountId": { + "value": "[parameters('storageAccountResourceId')]" + }, + "logAnalyticsWorkspaceResourceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + }, + "logs": { + "value": "[parameters('keyVaultDiagnosticLogs')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "1721966359516622278" + } + }, + "parameters": { + "keyVaultDiagnosticSettingName": { + "type": "string" + }, + "keyVaultName": { + "type": "string" + }, + "keyVaultStorageAccountId": { + "type": "string" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string" + }, + "logs": { + "type": "array" + } + }, + "resources": [ + { + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2017-05-01-preview", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', parameters('keyVaultName'))]", + "name": "[parameters('keyVaultDiagnosticSettingName')]", + "properties": { + "storageAccountId": "[parameters('keyVaultStorageAccountId')]", + "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]", + "logs": "[parameters('logs')]" + } + } + ] + } } }, { - "condition": "[parameters('enableAvdInsights')]", - "type": "Microsoft.Insights/dataCollectionRules", - "apiVersion": "2022-06-01", - "name": "[format('microsoft-avdi-{0}', replace(parameters('namingConvention').dataCollectionRule, parameters('serviceToken'), parameters('service')))]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Insights/dataCollectionRules'), parameters('tags')['Microsoft.Insights/dataCollectionRules'], createObject()), parameters('mlzTags'))]", - "kind": "Windows", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-nsg-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { - "dataSources": { - "performanceCounters": [ - { - "streams": [ - "Microsoft-Perf" - ], - "samplingFrequencyInSeconds": 30, - "counterSpecifiers": [ - "\\LogicalDisk(C:)\\Avg. Disk Queue Length", - "\\LogicalDisk(C:)\\Current Disk Queue Length", - "\\Memory\\Available Mbytes", - "\\Memory\\Page Faults/sec", - "\\Memory\\Pages/sec", - "\\Memory\\% Committed Bytes In Use", - "\\PhysicalDisk(*)\\Avg. Disk Queue Length", - "\\PhysicalDisk(*)\\Avg. Disk sec/Read", - "\\PhysicalDisk(*)\\Avg. Disk sec/Transfer", - "\\PhysicalDisk(*)\\Avg. Disk sec/Write", - "\\Processor Information(_Total)\\% Processor Time", - "\\User Input Delay per Process(*)\\Max Input Delay", - "\\User Input Delay per Session(*)\\Max Input Delay", - "\\RemoteFX Network(*)\\Current TCP RTT", - "\\RemoteFX Network(*)\\Current UDP Bandwidth" - ], - "name": "perfCounterDataSource10" + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceResourceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + }, + "logs": { + "value": "[parameters('networkSecurityGroupDiagnosticsLogs')]" + }, + "logStorageAccountResourceId": { + "value": "[parameters('storageAccountResourceId')]" + }, + "metrics": { + "value": "[parameters('networkSecurityGroupDiagnosticsMetrics')]" + }, + "networkSecurityGroupDiagnosticSettingName": { + "value": "[parameters('tier').namingConvention.networkSecurityGroupDiagnosticSetting]" + }, + "networkSecurityGroupName": { + "value": "[parameters('networkSecurityGroupName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "2073766618455932098" + } + }, + "parameters": { + "logAnalyticsWorkspaceResourceId": { + "type": "string" }, - { - "streams": [ - "Microsoft-Perf" - ], - "samplingFrequencyInSeconds": 60, - "counterSpecifiers": [ - "\\LogicalDisk(C:)\\% Free Space", - "\\LogicalDisk(C:)\\Avg. Disk sec/Transfer", - "\\Terminal Services(*)\\Active Sessions", - "\\Terminal Services(*)\\Inactive Sessions", - "\\Terminal Services(*)\\Total Sessions" - ], - "name": "perfCounterDataSource30" + "logs": { + "type": "array" + }, + "logStorageAccountResourceId": { + "type": "string" + }, + "metrics": { + "type": "array" + }, + "networkSecurityGroupDiagnosticSettingName": { + "type": "string" + }, + "networkSecurityGroupName": { + "type": "string" } - ], - "windowsEventLogs": [ + }, + "resources": [ { - "streams": [ - "Microsoft-Event" - ], - "xPathQueries": [ - "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Admin!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]", - "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]", - "System!*", - "Microsoft-FSLogix-Apps/Operational!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]", - "Application!*[System[(Level=2 or Level=3)]]", - "Microsoft-FSLogix-Apps/Admin!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]" - ], - "name": "eventLogsDataSource" + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2017-05-01-preview", + "scope": "[format('Microsoft.Network/networkSecurityGroups/{0}', parameters('networkSecurityGroupName'))]", + "name": "[parameters('networkSecurityGroupDiagnosticSettingName')]", + "properties": { + "storageAccountId": "[parameters('logStorageAccountResourceId')]", + "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]", + "logs": "[parameters('logs')]", + "metrics": "[parameters('metrics')]" + } } ] + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-vnet-diags-{0}-{1}', parameters('tier').shortName, parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tier').subscriptionId]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" }, - "destinations": { - "logAnalytics": [ + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceResourceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + }, + "logs": { + "value": "[parameters('virtualNetworkDiagnosticsLogs')]" + }, + "logStorageAccountResourceId": { + "value": "[parameters('storageAccountResourceId')]" + }, + "metrics": { + "value": "[parameters('virtualNetworkDiagnosticsMetrics')]" + }, + "virtualNetworkDiagnosticSettingName": { + "value": "[parameters('tier').namingConvention.virtualNetworkDiagnosticSetting]" + }, + "virtualNetworkName": { + "value": "[parameters('virtualNetworkName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "9546260853018527046" + } + }, + "parameters": { + "logAnalyticsWorkspaceResourceId": { + "type": "string" + }, + "logs": { + "type": "array" + }, + "logStorageAccountResourceId": { + "type": "string" + }, + "metrics": { + "type": "array" + }, + "virtualNetworkDiagnosticSettingName": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + } + }, + "resources": [ { - "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]", - "name": "la-workspace" + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2017-05-01-preview", + "scope": "[format('Microsoft.Network/virtualNetworks/{0}', parameters('virtualNetworkName'))]", + "name": "[parameters('virtualNetworkDiagnosticSettingName')]", + "properties": { + "storageAccountId": "[parameters('logStorageAccountResourceId')]", + "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]", + "logs": "[parameters('logs')]", + "metrics": "[parameters('metrics')]" + } } ] - }, - "dataFlows": [ - { - "streams": [ - "Microsoft-Perf", - "Microsoft-Event" - ], - "destinations": [ - "la-workspace" - ] - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" - ] - }, - { - "condition": "[parameters('enableAvdInsights')]", - "type": "Microsoft.Insights/dataCollectionEndpoints", - "apiVersion": "2021-04-01", - "name": "[replace(parameters('namingConvention').dataCollectionEndpoint, parameters('serviceToken'), parameters('service'))]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Insights/dataCollectionEndpoints'), parameters('tags')['Microsoft.Insights/dataCollectionEndpoints'], createObject()), parameters('mlzTags'))]", - "kind": "Windows", - "properties": { - "networkAcls": { - "publicNetworkAccess": "Disabled" } } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] + }, + { + "condition": "[and(parameters('deployPolicy'), not(empty(parameters('virtualNetworkAddressPrefix'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('assign-policy-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "logAnalyticsWorkspaceResourceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + }, + "tiers": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value]" + }, + "policy": { + "value": "[parameters('policy')]" + }, + "resourceGroupNames": { + "value": [ + "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + ] + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "15014526386353172066" + } + }, + "parameters": { + "deploymentNameSuffix": { + "type": "string" + }, + "location": { + "type": "string" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string" + }, + "policy": { + "type": "string" + }, + "resourceGroupNames": { + "type": "array" }, + "tiers": { + "type": "array" + } + }, + "resources": [ { + "copy": { + "name": "policyAssignment", + "count": "[length(parameters('tiers'))]" + }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-private-link-scope-law-{0}', parameters('deploymentNameSuffix'))]", - "subscriptionId": "[split(parameters('privateLinkScopeResourceId'), '/')[2]]", - "resourceGroup": "[split(parameters('privateLinkScopeResourceId'), '/')[4]]", + "name": "[format('assign-policy-{0}-{1}', parameters('tiers')[copyIndex()].name, parameters('deploymentNameSuffix'))]", + "subscriptionId": "[parameters('tiers')[copyIndex()].subscriptionId]", + "resourceGroup": "[parameters('resourceGroupNames')[copyIndex()]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { + "builtInAssignment": { + "value": "[parameters('policy')]" + }, "logAnalyticsWorkspaceResourceId": { - "value": "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" }, - "privateLinkScopeResourceId": { - "value": "[parameters('privateLinkScopeResourceId')]" + "location": { + "value": "[parameters('location')]" } }, "template": { @@ -7786,224 +5176,961 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "8149225552603313421" + "version": "0.31.92.45157", + "templateHash": "8545903679924437739" } }, "parameters": { - "applicationInsightsResourceId": { - "type": "string", - "defaultValue": "" - }, - "dataCollectionEndpointResourceId": { + "builtInAssignment": { "type": "string", - "defaultValue": "" + "defaultValue": "NISTRev4", + "allowedValues": [ + "NISTRev4", + "NISTRev5", + "IL5", + "CMMC" + ], + "metadata": { + "description": "[NISTRev4/NISTRev5/IL5/CMMC] Built-in policy assignments to assign, default is NISTRev4. IL5 is only available for AzureUsGovernment and will switch to NISTRev4 if tried in AzureCloud." + } }, "logAnalyticsWorkspaceResourceId": { - "type": "string", - "defaultValue": "" - }, - "privateLinkScopeResourceId": { "type": "string" + }, + "deployRemediation": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Starts a policy remediation for the VM Agent policies in hub RG. Set to false by default since this is time consuming in deployment." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "The location of this resource" + } } }, + "variables": { + "$fxv#0": " {\r\n \"listOfMembersToExcludeFromWindowsVMAdministratorsGroup\": \r\n {\r\n \"value\": \"admin\"\r\n },\r\n \"listOfMembersToIncludeInWindowsVMAdministratorsGroup\": \r\n {\r\n \"value\": \"azureuser\"\r\n },\r\n \"logAnalyticsWorkspaceIdforVMReporting\": \r\n {\r\n \"value\": \"\"\r\n },\r\n \"IncludeArcMachines\": \r\n {\r\n \"value\": \"true\"\r\n },\r\n \"MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112\": \r\n {\r\n \"value\": \"1.2\"\r\n },\r\n \"NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40\": \r\n {\r\n \"value\": \"Compliant\"\r\n },\r\n \"requiredRetentionDays\": \r\n {\r\n \"value\": \"365\"\r\n },\r\n \"resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6\": \r\n {\r\n \"value\": \"NetworkWatcherRG\"\r\n }\r\n }", + "$fxv#1": " {\r\n \"IncludeArcMachines\": \r\n {\r\n \"value\": \"true\"\r\n },\r\n \"MinimumTLSVersion-5752e6d6-1206-46d8-8ab1-ecc2f71a8112\": \r\n {\r\n \"value\": \"1.2\"\r\n },\r\n \"NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40\": \r\n {\r\n \"value\": \"Compliant\"\r\n },\r\n \"requiredRetentionDays\": \r\n {\r\n \"value\": \"365\"\r\n },\r\n \"resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6\": \r\n {\r\n \"value\": \"NetworkWatcherRG\"\r\n }\r\n }", + "$fxv#2": "{\r\n \"IncludeArcMachines\" : { \r\n \"value\" : \"false\"\r\n },\r\n \"NotAvailableMachineState-bed48b13-6647-468e-aa2f-1af1d3f4dd40\" : { \r\n \"value\" : \"Compliant\"\r\n },\r\n \"MinimumTLSVersionForWindowsServers\" : { \r\n \"value\" : \"1.2\"\r\n },\r\n \"requiredRetentionDays\" : { \r\n \"value\" : \"365\"\r\n },\r\n \"effect-febd0533-8e55-448f-b837-bd0e06f16469\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"allowedContainerImagesRegex-febd0533-8e55-448f-b837-bd0e06f16469\" : { \r\n \"value\" : \"^(.+){0}$\"\r\n },\r\n \"effect-95edb821-ddaf-4404-9732-666045e056b4\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-440b515e-a580-421e-abeb-b159a61ddcbc\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-233a2a17-77ca-4fb1-9b6b-69223d272a44\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-e345eecc-fa47-480f-9e88-67dcc122b164\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"cpuLimit-e345eecc-fa47-480f-9e88-67dcc122b164\" : { \r\n \"value\" : \"0\"\r\n },\r\n \"memoryLimit-e345eecc-fa47-480f-9e88-67dcc122b164\" : { \r\n \"value\" : \"0\"\r\n },\r\n \"effect-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"runAsUserRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"MustRunAsNonRoot\"\r\n },\r\n \"runAsGroupRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"RunAsAny\"\r\n },\r\n \"supplementalGroupsRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"RunAsAny\"\r\n },\r\n \"fsGroupRule-f06ddb64-5fa3-4b77-b166-acb36f7f6042\" : { \r\n \"value\" : \"RunAsAny\"\r\n },\r\n \"effect-1c6e92c9-99f0-4e55-9cf2-0c234dc48f99\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-47a1ee2f-2a2a-4576-bf2a-e0e36709c2b8\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-df49d893-a74c-421d-bc95-c663042e5b80\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-1a5b4dca-0b6f-4cf5-907c-56316bc1bf3d\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-c26596ff-4d70-4e6a-9a30-c2506bd2f80c\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-511f5417-5d12-434d-ab2e-816901e72a5e\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-82985f06-dc18-4a48-bc1c-b9f4f0098cfe\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-098fc59e-46c7-4d99-9b16-64990e543d75\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"NetworkWatcherResourceGroupName\" : { \r\n \"value\" : \"NetworkWatcherRG\"\r\n },\r\n \"setting-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9\" : { \r\n \"value\" : \"enabled\"\r\n },\r\n \"aadAuthenticationInServiceFabricMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-71ef260a-8f18-47b7-abcb-62d0673d94dc\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-055aa869-bc98-4af8-bafc-23f1ab6ffe2c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-564feb30-bf6a-4854-b4bb-0d2d2d1e6c66\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-862e97cf-49fc-4a5c-9de4-40d4e2e7c8eb\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d9da03a1-f3c3-412a-9709-947156872263\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-617c02be-7f02-4efd-8836-3180d47b6c68\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0b60c0b2-2dc2-4e1c-b5c9-abbed971de53\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ec068d99-e9c7-401f-8cef-5bdde4e6ccf1\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c349d81b-9985-44ae-a8da-ff98d108ede8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-3657f5a0-770e-44a3-b44e-9431ba1e9735\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-b4ac1030-89c5-4697-8e00-28b5ba6a8811\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-ea0dfaed-95fb-448c-934e-d6e713ce393d\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-4733ea7b-a883-42fe-8cac-97454c2a9e4a\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-f4b53539-8df9-40e4-86c6-6b607703bd4e\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-41425d9f-d1a5-499a-9932-f8ed8453932c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-fc4d8e41-e223-45ea-9bf5-eada37891d87\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-86efb160-8de7-451d-bc08-5d475b0aadae\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-4ec52d6d-beb7-40c4-9a9e-fe753254690e\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-64d314f6-6062-4780-a861-c23e8951bee5\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1fd32ebd-e4c3-4e13-a54a-d7422d4d95f6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-fa298e57-9444-42ba-bf04-86e8470e32c7\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-67121cc7-ff39-4ab8-b7e3-95b84dab487d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1f905d99-2ab7-462c-a6b0-f709acca6c8f\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-5b9159ae-1701-4a6f-9a7a-aa9c8ddd0580\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ba769a63-b8cc-4b2d-abf6-ac33c7204be8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-81e74cea-30fd-40d5-802f-d72103c2aaaa\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0aa61e00-0a01-4a3c-9945-e93cffedf0e6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-47031206-ce96-41f8-861b-6a915f3de284\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-87ba29ef-1ab3-4d82-b763-87fcd4f531f7\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-51522a96-0869-4791-82f3-981000c2c67f\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-b5ec538c-daa0-4006-8596-35468b9148e8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-56a5ee18-2ae6-4810-86f7-18e39ce5629b\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-2e94d99a-8a36-4563-bc77-810d8893b671\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1fafeaf6-7927-4059-a50a-8eb2a7a6f2b5\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-99e9ccd8-3db9-4592-b0d1-14b1715a4d8a\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1f68a601-6e6d-4e42-babf-3f643a047ea2\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-f7d52b2d-e161-4dfa-a82b-55e564167385\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7d7be79c-23ba-4033-84dd-45e2a5ccdd67\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ca91455f-eace-4f96-be59-e6e2c35b4816\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-702dd420-7fcc-42c5-afe8-4026edd20fe0\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"diagnosticsLogsInRedisCacheMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"secureTransferToStorageAccountMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d0793b48-0edc-4296-a390-4c75d1bdfd71\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7d092e0a-7acd-40d2-a975-dca21cae48c4\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-2a1a9cdf-e04d-429a-8416-3bfb72a1b26f\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"disableUnrestrictedNetworkToStorageAccountMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-55615ac9-af46-4a59-874e-391cc3dfb490\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1b8ca024-1d5c-4dec-8995-b1a932b41780\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-037eea7a-bd0a-46c5-9a66-03aea78705d3\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-53503636-bcc9-4748-9663-5348217f160f\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-40cec1dd-a100-4920-b15b-3024fe8901ab\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0725b4dd-7e76-479c-a735-68e7ee23d5ca\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-a049bf77-880b-470f-ba6d-9f21c530cf83\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ee980b6d-0eca-4501-8d54-f6290fd512c3\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1d84d5fb-01f6-4d12-ba4f-4a26081d403d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-37e0d2fe-28a5-43d6-a273-67d37d1f5606\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"identityDesignateMoreThanOneOwnerMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"diskEncryptionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"emailNotificationToSubscriptionOwnerHighSeverityAlertsEnabledEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"functionAppDisableRemoteDebuggingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"sqlDbEncryptionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vulnerabilityAssessmentOnManagedInstanceMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePHPVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"aadAuthenticationInSqlServerMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vmssEndpointProtectionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vmssOsVulnerabilitiesMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"adaptiveApplicationControlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"geoRedundantBackupShouldBeEnabledForAzureDatabaseForPostgreSQLEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"ensureJavaVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityDesignateLessThanOwnersMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"securityContactEmailAddressForSubscriptionEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"webAppRestrictCORSAccessMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveExternalAccountWithWritePermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveExternalAccountWithReadPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveDeprecatedAccountMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"functionAppEnforceHttpsMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"ensurePythonVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePythonVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePHPVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensurePythonVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"geoRedundantBackupShouldBeEnabledForAzureDatabaseForMySQLEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"systemUpdatesMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureJavaVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureHTTPVersionLatestForWebAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"apiAppRequireLatestTlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityEnableMFAForWritePermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureHTTPVersionLatestForAPIAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureJavaVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"nextGenerationFirewallMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"useRbacRulesMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"webAppEnforceHttpsMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"sqlServerAuditingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vnetEnableDDoSProtectionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityEnableMFAForOwnerPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"sqlServerAdvancedDataSecurityMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"sqlManagedInstanceAdvancedDataSecurityMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"endpointProtectionMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"jitNetworkAccessMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"apiAppEnforceHttpsMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"geoRedundantStorageShouldBeEnabledForStorageAccountsEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"vmssSystemUpdatesMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"webAppDisableRemoteDebuggingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"longtermGeoRedundantBackupEnabledAzureSQLDatabasesEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"systemConfigurationsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"ensureHTTPVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityEnableMFAForReadPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"containerBenchmarkMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"apiAppDisableRemoteDebuggingMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveDeprecatedAccountWithOwnerPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"vulnerabilityAssessmentOnServerMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"webAppRequireLatestTlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"identityRemoveExternalAccountWithOwnerPermissionsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"functionAppRequireLatestTlsMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"kubernetesServiceVersionUpToDateMonitoringEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"sqlDbVulnerabilityAssesmentMonitoringEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"membersToIncludeInLocalAdministratorsGroup\" : { \r\n \"value\" : \"\"\r\n },\r\n \"membersToExcludeInLocalAdministratorsGroup\" : { \r\n \"value\" : \"\"\r\n },\r\n \"logAnalyticsWorkspaceIDForVMAgents\" : { \r\n \"value\" : \"\"\r\n },\r\n \"PHPLatestVersionForAppServices\" : { \r\n \"value\" : \"7.4\"\r\n },\r\n \"JavaLatestVersionForAppServices\" : { \r\n \"value\" : \"11\"\r\n },\r\n \"WindowsPythonLatestVersionForAppServices\" : { \r\n \"value\" : \"3.6\"\r\n },\r\n \"LinuxPythonLatestVersionForAppServices\" : { \r\n \"value\" : \"3.9\"\r\n },\r\n \"ensureDotNetFrameworkLatestForFunctionAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlManagedInstanceAdvancedDataSecurityEmailsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"vulnerabilityAssessmentMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"ensureDotNetFrameworkLatestForWebAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlServerAdvancedDataSecurityEmailsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"microsoftIaaSAntimalwareExtensionShouldBeDeployedOnWindowsServersEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"securityCenterStandardPricingTierShouldBeSelectedEffect\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"theLogAnalyticsAgentShouldBeInstalledOnVirtualMachinesEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"ensurePHPVersionLatestForFunctionAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlManagedInstanceAdvancedDataSecurityEmailAdminsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"securityContactPhoneNumberShouldBeProvidedForSubscriptionEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"threatDetectionTypesOnManagedInstanceMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"ensureDotNetFrameworkLatestForAPIAppEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"sqlServerAdvancedDataSecurityEmailAdminsMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"threatDetectionTypesOnServerMonitoringEffect\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"theLogAnalyticsAgentShouldBeInstalledOnVirtualMachineScaleSetsEffect\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n }\r\n}", + "$fxv#3": "{\r\n \"logAnalyticsWorkspaceId-f47b5582-33ec-4c5c-87c0-b010a6b2e917\" : { \r\n \"value\" : \"\"\r\n },\r\n \"effect-09024ccc-0c5f-475e-9457-b7c0d9ed487b\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"MembersToExclude-69bf4abd-ca1e-4cf6-8b5a-762d42e61d4f\" :{\r\n \"value\": \"\"\r\n },\r\n \"MembersToInclude-30f71ea1-ac77-4f26-9fc5-2d926bbd4ba7\": {\r\n \"value\": \"\"\r\n },\r\n \"effect-0961003e-5a0a-4549-abde-af6a37f2724d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0b15565f-aa9e-48ba-8619-45960f2c314d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0e60b895-3786-45da-8377-9c6b4b6ac5f9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-17k78e20-9358-41c9-923c-fb736d382a12\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-1bc1795e-d44a-4d48-9b3b-6fff0fd5f9ba\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"PHPLatestVersion\" : { \r\n \"value\" : \"7.3\"\r\n },\r\n \"effect-22bee202-a82f-4305-9a2a-6d7f44d4dedb\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-26a828e1-e88f-464e-bbb3-c134a282b9de\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-34c877ad-507e-4c82-993e-3452a6e0ad3c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-3c735d8a-a4ba-4a3a-b7cf-db7754cf57f4\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-404c3081-a854-4457-ae30-26a93ef643f9\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-47a6b606-51aa-4496-8bb7-64b11cf66adc\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-496223c3-ad65-4ecd-878a-bae78737e9ed\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"JavaLatestVersion\" : { \r\n \"value\" : \"11\"\r\n },\r\n \"effect-4f11b553-d42e-4e3a-89be-32ca364cad4c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-4f4f78b8-e367-4b10-a341-d9a4ad5cf1c7\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-5c607a2e-c700-4744-8254-d77e7c9eb5e4\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-5f76cf89-fbf2-47fd-a3f4-b891fa780b60\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-6b1cbf55-e8b6-442f-ba4c-7246b6381474\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-6d555dd1-86f2-4f1c-8ed7-5abae7c6cbab\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7008174a-fd10-4ef0-817e-fc820a951d73\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"LinuxPythonLatestVersion\" : { \r\n \"value\" : \"3.8\"\r\n },\r\n \"effect-7238174a-fd10-4ef0-817e-fc820a951d73\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-7261b898-8a84-4db8-9e04-18527132abb3\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-74c3584d-afae-46f7-a20a-6f8adba71a16\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-86b3d65f-7626-441e-b690-81a8b71cff60\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-88999f4c-376a-45c8-bcb3-4058f713cf39\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-8c122334-9d20-4eb8-89ea-ac9a705b74ae\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-8cb6aa8b-9e41-4f4e-aa25-089a7ac2581e\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9297c21d-2ed6-4474-b48f-163f75654ce3\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-991310cd-e9f3-47bc-b7b6-f57b557d07db\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9b597639-28e4-48eb-b506-56b05d366257\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9d0b6ea4-93e2-4578-bf2f-6bb17d22b4bc\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-9daedab3-fb2d-461e-b861-71790eead4f6\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-a4af4a39-4135-47fb-b175-47fbdf85311d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"setting-a6fb4358-5bf4-4ad7-ba82-2cd2f41ce5e9\" : { \r\n \"value\" : \"enabled\"\r\n },\r\n \"effect-a70ca396-0a34-413a-88e1-b956c1e683be\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-aa633080-8b72-40c4-a2d7-d00c03e80bed\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-abfb4388-5bf4-4ad7-ba82-2cd2f41ceae9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-abfb7388-5bf4-4ad7-ba99-2cd2f41cebb9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-af6cd1bd-1635-48cb-bde7-5b15693900b9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"resourceGroupName-b6e2945c-0b7b-40f5-9233-7a5323b5cdc6\" : { \r\n \"value\" : \"NetworkWatcherRG\"\r\n },\r\n \"effect-b7ddfbdc-1260-477d-91fd-98bd9be789a6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c3f317a7-a95c-4547-b7e7-11017ebdf2fe\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-cb510bfd-1cba-4d9f-a230-cb0976f4bb71\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e1e5fd5d-3e4c-4ce1-8661-7d1873ae6b15\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e2c1c086-2d84-4019-bff3-c44ccd95113c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e3576e28-8b17-4677-84c3-db2990658d64\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e8cbc669-f12d-49eb-93e7-9273119e9933\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e9c8d085-d9cc-4b17-9cdc-059f1f01f19e\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ebb62a0c-3560-49e1-89ed-27e074e9f8ad\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-efbde977-ba53-4479-b8e9-10b957924fbf\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f0e6e85b-9b9f-4a4b-b67b-f730d42f1b0b\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f6de0be7-9a8a-4b8a-b349-43cf02d22f7c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f8456c1c-aa66-4dfb-861a-25d127b775c9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-f9d614c5-c173-4d56-95a7-b4437057d193\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-fb893a29-21bb-418c-a157-e99480ec364c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-feedbf84-6b99-488c-acc2-71c829aa5ffc\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-3b980d31-7904-4bb7-8575-5665739a8052\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-6e2593d9-add6-4083-9c9b-4b7d2188c899\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b607c5de-e7d9-4eee-9e5c-83f1bcee4fa0\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-12430be1-6cc8-4527-a9a8-e3d38f250096\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"modeRequirement-12430be1-6cc8-4527-a9a8-e3d38f250096\" : { \r\n \"value\" : \"Detection\"\r\n },\r\n \"effect-425bea59-a659-4cbb-8d31-34499bd030b8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"modeRequirement-425bea59-a659-4cbb-8d31-34499bd030b8\" : { \r\n \"value\" : \"Detection\"\r\n },\r\n \"effect-564feb30-bf6a-4854-b4bb-0d2d2d1e6c66\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-055aa869-bc98-4af8-bafc-23f1ab6ffe2c\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-013e242c-8828-4970-87b3-ab247555486d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-d38fc420-0735-4ef3-ac11-c806f651a570\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-a1181c5f-672a-477a-979a-7d58aa086233\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-308fbb08-4ab8-4e67-9b29-592e93fb94fa\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-4da35fc9-c9e7-4960-aec9-797fe7d9051d\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-523b5cd1-3e23-492f-a539-13118b6d1e3a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-7fe3b40f-802b-4cdd-8bd4-fd799c948cc2\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-c25d9a16-bc35-4e15-a7e5-9db606bf9ed4\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b0f33259-77d7-4c9e-aac6-3aabcfae693c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-037eea7a-bd0a-46c5-9a66-03aea78705d3\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0725b4dd-7e76-479c-a735-68e7ee23d5ca\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-0820b7b9-23aa-4725-a1ce-ae4558f718e5\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-2c89a2e5-7285-40fe-afe0-ae8654b92fab\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-358c20a6-3f9e-4f0e-97ff-c6ce485e2aac\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-5744710e-cc2f-4ee8-8809-3b11e89f4bc9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ac4a19c2-fa67-49b4-8ae5-0b2e78c49457\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c9d007d0-c057-4772-b18c-01e546713bcd\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d0793b48-0edc-4296-a390-4c75d1bdfd71\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-e372f825-a257-4fb8-9175-797a8a8627d6\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-d158790f-bfb0-486c-8631-2dc6b4e8e6af\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-e802a67a-daf5-4436-9ea6-f6d821dd0c5d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-a451c1ef-c6ca-483d-87ed-f49761e3ffb5\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftSql-servers-firewallRules-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftNetwork-networkSecurityGroups-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftClassicNetwork-networkSecurityGroups-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftNetwork-networkSecurityGroups-securityRules-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b954148f-4c11-4c38-8221-be76711e194a-MicrosoftClassicNetwork-networkSecurityGroups-securityRules-delete\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ae89ebca-1c92-4898-ac2c-9f63decb045c\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-d26f7642-7545-4e18-9b75-8c9bbdee3a9a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-1a4e592a-6a6e-44a5-9814-e36264ca96e7\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-7796937f-307b-4598-941c-67d3a05ebfe7\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-c5447c04-a4d7-4ba8-a263-c9ee321a6858\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-41388f1c-2db0-4c25-95b2-35d7f5ccbfa9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-b02aacc0-b073-424e-8298-42b22829ee0a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-057d6cfe-9c4f-4a6d-bc60-14420ea1f1a9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0ec47710-77ff-4a3d-9181-6aa50af424d0\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-48af4db5-9b8b-401c-8e74-076be876a430\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-82339799-d096-41ae-8538-b108becf0970\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1b7aa243-30e4-4c9e-bca8-d0d3022b634a\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-ef2a8f2a-b3d9-49cd-a8a8-9a3aaaf647d9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-bb91dfba-c30d-4263-9add-9c2384e659a6\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-e71308d3-144b-4262-b144-efdc3cc90517\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-2bdd0062-9d75-436e-89df-487dd8e4b3c7\" : { \r\n \"value\" : \"Disabled\"\r\n },\r\n \"effect-4733ea7b-a883-42fe-8cac-97454c2a9e4a\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-67121cc7-ff39-4ab8-b7e3-95b84dab487d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-6fac406b-40ca-413b-bf8e-0bf964659c25\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-81e74cea-30fd-40d5-802f-d72103c2aaaa\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c349d81b-9985-44ae-a8da-ff98d108ede8\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-f4b53539-8df9-40e4-86c6-6b607703bd4e\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-ec068d99-e9c7-401f-8cef-5bdde4e6ccf1\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-048248b0-55cd-46da-b1ff-39efd52db260\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0d134df8-db83-46fb-ad72-fe0c9428c8dd\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-2c89a2e5-7285-40fe-afe0-ae8654b92fb2\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-3657f5a0-770e-44a3-b44e-9431ba1e9735\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-5b9159ae-1701-4a6f-9a7a-aa9c8ddd0580\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-617c02be-7f02-4efd-8836-3180d47b6c68\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-7d7be79c-23ba-4033-84dd-45e2a5ccdd67\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-87ba29ef-1ab3-4d82-b763-87fcd4f531f7\" : { \r\n \"value\" : \"audit\"\r\n },\r\n \"effect-f7d52b2d-e161-4dfa-a82b-55e564167385\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-c43e4a30-77cb-48ab-a4dd-93f175c63b57\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-0b60c0b2-2dc2-4e1c-b5c9-abbed971de53\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1e66c121-a66a-4b1f-9b83-0fd99bf0fc2d\" : { \r\n \"value\" : \"Audit\"\r\n },\r\n \"effect-1f314764-cb73-4fc9-b863-8eca98ac36e9\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n },\r\n \"effect-123a3936-f020-408a-ba0c-47873faf1534\" : { \r\n \"value\" : \"AuditIfNotExists\"\r\n }\r\n}\r\n", + "modifiedAssignment": "[if(and(equals(toLower(environment().name), toLower('AzureCloud')), equals(toLower(parameters('builtInAssignment')), toLower('IL5'))), 'NISTRev4', parameters('builtInAssignment'))]", + "assignmentName": "[format('{0} {1}', variables('modifiedAssignment'), resourceGroup().name)]", + "agentVmssAssignmentName": "[format('Deploy VMSS Agents {0}', resourceGroup().name)]", + "agentVmAssignmentName": "[format('Deploy VM Agents {0}', resourceGroup().name)]", + "contributorRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", + "lawsReaderRoleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293')]" + }, "resources": [ { - "condition": "[not(empty(parameters('applicationInsightsResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('applicationInsightsResourceId')), 'applicationInsights', split(parameters('applicationInsightsResourceId'), '/')[8]))]", + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2020-09-01", + "name": "[variables('assignmentName')]", + "location": "[parameters('location')]", "properties": { - "linkedResourceId": "[parameters('applicationInsightsResourceId')]" + "policyDefinitionId": "[createObject('NISTRev4', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/cf25b9c1-bd23-4eb6-bd2c-f4f3ac644a5f', 'parameters', json(replace(variables('$fxv#0'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'NISTRev5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/179d1daa-458f-4e47-8086-2a68d0d6c38f', 'parameters', json(variables('$fxv#1'))), 'IL5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/f9a961fa-3241-4b20-adc4-bbf8ad9d7197', 'parameters', json(replace(variables('$fxv#2'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'CMMC', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/b5629c75-5c77-4422-87b9-2509e680f8de', 'parameters', json(replace(variables('$fxv#3'), '', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]), '2021-06-01').customerId))))[variables('modifiedAssignment')].id]", + "parameters": "[createObject('NISTRev4', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/cf25b9c1-bd23-4eb6-bd2c-f4f3ac644a5f', 'parameters', json(replace(variables('$fxv#0'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'NISTRev5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/179d1daa-458f-4e47-8086-2a68d0d6c38f', 'parameters', json(variables('$fxv#1'))), 'IL5', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/f9a961fa-3241-4b20-adc4-bbf8ad9d7197', 'parameters', json(replace(variables('$fxv#2'), '', extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])))), 'CMMC', createObject('id', '/providers/Microsoft.Authorization/policySetDefinitions/b5629c75-5c77-4422-87b9-2509e680f8de', 'parameters', json(replace(variables('$fxv#3'), '', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]), '2021-06-01').customerId))))[variables('modifiedAssignment')].parameters]" + }, + "identity": { + "type": "SystemAssigned" + } + }, + { + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2020-09-01", + "name": "[variables('agentVmssAssignmentName')]", + "location": "[parameters('location')]", + "properties": { + "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policySetDefinitions', '75714362-cae7-409e-9b99-a8e5075b7fad')]", + "parameters": { + "logAnalytics_1": { + "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])]" + } + } + }, + "identity": { + "type": "SystemAssigned" + } + }, + { + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2020-09-01", + "name": "[variables('agentVmAssignmentName')]", + "location": "[parameters('location')]", + "properties": { + "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policySetDefinitions', '55f3eceb-5573-4f18-9695-226972c6d74a')]", + "parameters": { + "logAnalytics_1": { + "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])]" + } + } + }, + "identity": { + "type": "SystemAssigned" } }, { - "condition": "[not(empty(parameters('dataCollectionEndpointResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('dataCollectionEndpointResourceId')), 'dataCollectionEndpoint', split(parameters('dataCollectionEndpointResourceId'), '/')[8]))]", + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(variables('contributorRoleDefinitionId'), variables('assignmentName'))]", + "properties": { + "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", + "principalId": "[if(empty(variables('modifiedAssignment')), '', reference(resourceId('Microsoft.Authorization/policyAssignments', variables('assignmentName')), '2020-09-01', 'full').identity.principalId)]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.Authorization/policyAssignments', variables('assignmentName'))]" + ] + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(variables('contributorRoleDefinitionId'), variables('agentVmssAssignmentName'))]", + "properties": { + "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", + "principalId": "[reference(resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmssAssignmentName')), '2020-09-01', 'full').identity.principalId]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmssAssignmentName'))]" + ] + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(variables('contributorRoleDefinitionId'), variables('agentVmAssignmentName'))]", + "properties": { + "roleDefinitionId": "[variables('contributorRoleDefinitionId')]", + "principalId": "[reference(resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName')), '2020-09-01', 'full').identity.principalId]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]" + ] + }, + { + "condition": "[parameters('deployRemediation')]", + "type": "Microsoft.PolicyInsights/remediations", + "apiVersion": "2019-07-01", + "name": "VM-Agent-Policy-Remediation", "properties": { - "linkedResourceId": "[parameters('dataCollectionEndpointResourceId')]" - } + "policyAssignmentId": "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]", + "resourceDiscoveryMode": "ReEvaluateCompliance" + }, + "dependsOn": [ + "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]" + ] }, { - "condition": "[not(empty(parameters('logAnalyticsWorkspaceResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('logAnalyticsWorkspaceResourceId')), 'logAnalyticsWorkspace', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('Assign-Laws-Role-Policy-{0}', resourceGroup().name)]", + "subscriptionId": "[split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]]", "properties": { - "linkedResourceId": "[parameters('logAnalyticsWorkspaceResourceId')]" - } + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "targetResourceId": { + "value": "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[2], split(parameters('logAnalyticsWorkspaceResourceId'), '/')[4]), 'Microsoft.OperationalInsights/workspaces', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8])]" + }, + "roleDefinitionId": { + "value": "[variables('lawsReaderRoleDefinitionId')]" + }, + "principalId": { + "value": "[reference(resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName')), '2020-09-01', 'full').identity.principalId]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "1966035938992047983" + } + }, + "parameters": { + "targetResourceId": { + "type": "string" + }, + "roleDefinitionId": { + "type": "string" + }, + "principalId": { + "type": "string" + }, + "principalType": { + "type": "string", + "defaultValue": "ServicePrincipal", + "allowedValues": [ + "ForeignGroup", + "Group", + "ServicePrincipal", + "User" + ] + }, + "description": { + "type": "string", + "defaultValue": "" + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "name": "[guid(parameters('targetResourceId'), parameters('roleDefinitionId'), parameters('principalId'))]", + "properties": { + "principalId": "[parameters('principalId')]", + "principalType": "[parameters('principalType')]", + "roleDefinitionId": "[parameters('roleDefinitionId')]", + "description": "[parameters('description')]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Authorization/policyAssignments', variables('agentVmAssignmentName'))]" + ] } ] } - }, - "dependsOn": [ - "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" - ] + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix')))]" + ] + }, + { + "condition": "[and(parameters('deployDefender'), not(empty(parameters('virtualNetworkAddressPrefix'))))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('set-defender-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "emailSecurityContact": { + "value": "[parameters('emailSecurityContact')]" + }, + "logAnalyticsWorkspaceId": { + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "17047820191891552534" + } + }, + "parameters": { + "defenderPlans": { + "type": "array", + "defaultValue": [ + "VirtualMachines" + ], + "metadata": { + "description": "Defender Paid protection Plans. Even if a customer selects the free sku, at least 1 paid protection plan must be specified." + } }, - { - "condition": "[parameters('enableAvdInsights')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-private-link-scope-dce-{0}', parameters('deploymentNameSuffix'))]", - "subscriptionId": "[split(parameters('privateLinkScopeResourceId'), '/')[2]]", - "resourceGroup": "[split(parameters('privateLinkScopeResourceId'), '/')[4]]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" + "enableAutoProvisioning": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Turn automatic deployment by Defender of the MMA (OMS VM extension) on or off" + } + }, + "logAnalyticsWorkspaceId": { + "type": "string", + "metadata": { + "description": "Specify the ID of your custom Log Analytics workspace to collect Defender data." + } + }, + "emailSecurityContact": { + "type": "string", + "metadata": { + "description": "Email address of the contact, in the form of john@doe.com" + } + }, + "policySetDescription": { + "type": "string", + "defaultValue": "The Microsoft Cloud Security Benchmark initiative represents the policies and controls implementing security recommendations defined in Microsoft Cloud Security Benchmark v2, see https://aka.ms/azsecbm. This also serves as the Microsoft Defender for Cloud default policy initiative. You can directly assign this initiative, or manage its policies and compliance results within Microsoft Defender.", + "metadata": { + "description": "Policy Initiative description field" + } + }, + "defenderSkuTier": { + "type": "string", + "defaultValue": "Free", + "metadata": { + "description": "[Standard/Free] The SKU for Defender. It defaults to \"Free\"." + } + } + }, + "variables": { + "autoProvisioning": "[if(parameters('enableAutoProvisioning'), 'On', 'Off')]", + "defenderPaidPlanConfig": { + "AzureCloud": { + "Api": { + "subPlan": "P1" }, - "mode": "Incremental", - "parameters": { - "dataCollectionEndpointResourceId": { - "value": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', replace(parameters('namingConvention').dataCollectionEndpoint, parameters('serviceToken'), parameters('service')))]" - }, - "privateLinkScopeResourceId": { - "value": "[parameters('privateLinkScopeResourceId')]" - } + "appServices": {}, + "KeyVaults": { + "subPlan": "PerKeyVault" }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "8149225552603313421" - } - }, - "parameters": { - "applicationInsightsResourceId": { - "type": "string", - "defaultValue": "" + "Arm": { + "subPlan": "PerSubscription" + }, + "CloudPosture": { + "extensions": [ + { + "name": "SensitiveDataDiscovery", + "isEnabled": "True" }, - "dataCollectionEndpointResourceId": { - "type": "string", - "defaultValue": "" + { + "name": "ContainerRegistriesVulnerabilityAssessments", + "isEnabled": "True" }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "defaultValue": "" + { + "name": "AgentlessDiscoveryForKubernetes", + "isEnabled": "True" }, - "privateLinkScopeResourceId": { - "type": "string" - } - }, - "resources": [ { - "condition": "[not(empty(parameters('applicationInsightsResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('applicationInsightsResourceId')), 'applicationInsights', split(parameters('applicationInsightsResourceId'), '/')[8]))]", - "properties": { - "linkedResourceId": "[parameters('applicationInsightsResourceId')]" - } + "name": "AgentlessVmScanning", + "isEnabled": "True" + }, + { + "name": "EntraPermissionsManagement", + "isEnabled": "True" + } + ] + }, + "Containers": { + "extensions": [ + { + "name": "ContainerRegistriesVulnerabilityAssessments", + "isEnabled": "True" }, { - "condition": "[not(empty(parameters('dataCollectionEndpointResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('dataCollectionEndpointResourceId')), 'dataCollectionEndpoint', split(parameters('dataCollectionEndpointResourceId'), '/')[8]))]", - "properties": { - "linkedResourceId": "[parameters('dataCollectionEndpointResourceId')]" + "name": "AgentlessDiscoveryForKubernetes", + "isEnabled": "True" + } + ] + }, + "CosmosDbs": {}, + "StorageAccounts": { + "subPlan": "DefenderForStorageV2", + "extensions": [ + { + "name": "OnUploadMalwareScanning", + "isEnabled": "True", + "additionalExtensionProperties": { + "CapGBPerMonthPerStorageAccount": "5000" } }, { - "condition": "[not(empty(parameters('logAnalyticsWorkspaceResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('logAnalyticsWorkspaceResourceId')), 'logAnalyticsWorkspace', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]))]", - "properties": { - "linkedResourceId": "[parameters('logAnalyticsWorkspaceResourceId')]" - } + "name": "SensitiveDataDiscovery", + "isEnabled": "True" } ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Insights/dataCollectionEndpoints', replace(parameters('namingConvention').dataCollectionEndpoint, parameters('serviceToken'), parameters('service')))]" - ] + }, + "VirtualMachines": { + "subPlan": "P1" + }, + "SqlServerVirtualMachines": {}, + "SqlServers": {}, + "OpenSourceRelationalDatabases": {} + } } - ], - "outputs": { - "logAnalyticsWorkspaceName": { - "type": "string", - "value": "[replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service'))]" + }, + "resources": [ + { + "copy": { + "name": "defenderFreeAllClouds", + "count": "[length(parameters('defenderPlans'))]", + "mode": "serial", + "batchSize": 1 + }, + "condition": "[equals(parameters('defenderSkuTier'), 'Free')]", + "type": "Microsoft.Security/pricings", + "apiVersion": "2023-01-01", + "name": "[parameters('defenderPlans')[copyIndex()]]", + "properties": { + "pricingTier": "[parameters('defenderSkuTier')]" + } }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "value": "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" + { + "copy": { + "name": "defenderStandardNoSubplanNoExtensions", + "count": "[length(parameters('defenderPlans'))]", + "mode": "serial", + "batchSize": 1 + }, + "condition": "[and(equals(parameters('defenderSkuTier'), 'Standard'), not(equals(environment().name, 'AzureCloud')))]", + "type": "Microsoft.Security/pricings", + "apiVersion": "2023-01-01", + "name": "[parameters('defenderPlans')[copyIndex()]]", + "properties": { + "pricingTier": "[parameters('defenderSkuTier')]" + } }, - "dataCollectionRuleResourceId": { - "type": "string", - "value": "[if(parameters('enableAvdInsights'), resourceId('Microsoft.Insights/dataCollectionRules', format('microsoft-avdi-{0}', replace(parameters('namingConvention').dataCollectionRule, parameters('serviceToken'), parameters('service')))), '')]" + { + "copy": { + "name": "defenderStandardSubplanExtensionsAzureCloud", + "count": "[length(parameters('defenderPlans'))]", + "mode": "serial", + "batchSize": 1 + }, + "condition": "[and(equals(parameters('defenderSkuTier'), 'Standard'), equals(environment().name, 'AzureCloud'))]", + "type": "Microsoft.Security/pricings", + "apiVersion": "2023-01-01", + "name": "[parameters('defenderPlans')[copyIndex()]]", + "properties": { + "pricingTier": "[parameters('defenderSkuTier')]", + "subPlan": "[if(contains(variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]], 'subPlan'), variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]].subPlan, json('null'))]", + "extensions": "[if(contains(variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]], 'extensions'), variables('defenderPaidPlanConfig')[environment().name][parameters('defenderPlans')[copyIndex()]].extensions, json('null'))]" + } + }, + { + "type": "Microsoft.Security/autoProvisioningSettings", + "apiVersion": "2019-01-01", + "name": "default", + "properties": { + "autoProvision": "[variables('autoProvisioning')]" + } + }, + { + "type": "Microsoft.Security/workspaceSettings", + "apiVersion": "2019-01-01", + "name": "default", + "properties": { + "workspaceId": "[parameters('logAnalyticsWorkspaceId')]", + "scope": "[subscription().id]" + } + }, + { + "condition": "[not(empty(parameters('emailSecurityContact')))]", + "type": "Microsoft.Security/securityContacts", + "apiVersion": "2020-01-01-preview", + "name": "default", + "properties": { + "notificationsByRole": { + "roles": [ + "AccountAdmin", + "Contributor", + "Owner", + "ServiceAdmin" + ], + "state": "On" + }, + "alertNotifications": { + "state": "On" + }, + "emails": "[parameters('emailSecurityContact')]" + } + }, + { + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2022-06-01", + "name": "Microsoft Cloud Security Benchmark", + "properties": { + "displayName": "Defender Default", + "description": "[parameters('policySetDescription')]", + "enforcementMode": "DoNotEnforce", + "parameters": {}, + "policyDefinitionId": "[tenantResourceId('Microsoft.Authorization/policySetDefinitions', '1f3afdf9-d0c9-4c3d-847f-89da613e70a8')]" + } } - } + ] } } + } + ], + "outputs": { + "diskEncryptionSetResourceId": { + "type": "string", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskEncryptionSetResourceId.value, '')]" + }, + "dnsServers": { + "type": "array", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), coalesce(tryGet(reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01'), 'dhcpOptions', 'dnsServers'), createArray()), createArray())]" + }, + "keyVaultUri": { + "type": "string", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value, '')]" + }, + "locationProperties": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value]" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + }, + "mlzTags": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" + }, + "namingConvention": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0].namingConvention]" + }, + "privateDnsZones": { + "type": "array", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value]" + }, + "resourceAbbreviations": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" + }, + "resourcePrefix": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('firewallResourceId'), '/')[2], split(parameters('firewallResourceId'), '/')[4]), 'Microsoft.Network/azureFirewalls', split(parameters('firewallResourceId'), '/')[8]), '2020-11-01', 'full').tags.resourcePrefix]" + }, + "storageAccountResourceId": { + "type": "string", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-storage-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageAccountResourceId.value, '')]" + }, + "storageEncryptionKeyName": { + "type": "string", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageKeyName.value, '')]" + }, + "subnets": { + "type": "array", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-network-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value, createArray())]" + }, + "tier": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tiers.value[0]]" + }, + "tokens": { + "type": "object", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-logic-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value]" + }, + "userAssignedIdentityResourceId": { + "type": "string", + "value": "[if(not(empty(parameters('virtualNetworkAddressPrefix'))), reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-cmk-{0}-{1}', parameters('workloadShortName'), parameters('deploymentNameSuffix'))), '2022-09-01').outputs.userAssignedIdentityResourceId.value, '')]" + } + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-management-{0}', parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "activeDirectorySolution": { + "value": "[parameters('activeDirectorySolution')]" + }, + "avdObjectId": { + "value": "[parameters('avdObjectId')]" + }, + "avdPrivateDnsZoneResourceId": { + "value": "[format('{0}{1}', variables('privateDnsZoneResourceIdPrefix'), filter(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value, lambda('name', startsWith(lambdaVariables('name'), 'privatelink.wvd')))[0])]" + }, + "customImageId": { + "value": "[variables('customImageId')]" + }, + "customRdpProperty": { + "value": "[parameters('customRdpProperty')]" + }, + "deployFslogix": { + "value": "[variables('deployFslogix')]" + }, + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "desktopFriendlyName": "[if(empty(parameters('desktopFriendlyName')), createObject('value', string(parameters('stampIndex'))), createObject('value', parameters('desktopFriendlyName')))]", + "diskEncryptionSetResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskEncryptionSetResourceId.value]" + }, + "diskSku": { + "value": "[parameters('diskSku')]" + }, + "domainJoinPassword": { + "value": "[parameters('domainJoinPassword')]" + }, + "domainJoinUserPrincipalName": { + "value": "[parameters('domainJoinUserPrincipalName')]" + }, + "domainName": { + "value": "[parameters('domainName')]" + }, + "enableApplicationInsights": { + "value": "[parameters('enableApplicationInsights')]" + }, + "enableAvdInsights": { + "value": "[parameters('enableAvdInsights')]" + }, + "environmentAbbreviation": { + "value": "[parameters('environmentAbbreviation')]" + }, + "fslogixStorageService": { + "value": "[parameters('fslogixStorageService')]" + }, + "hostPoolPublicNetworkAccess": { + "value": "[parameters('hostPoolPublicNetworkAccess')]" + }, + "hostPoolType": { + "value": "[parameters('hostPoolType')]" + }, + "imageOffer": { + "value": "[parameters('imageOffer')]" + }, + "imagePublisher": { + "value": "[parameters('imagePublisher')]" + }, + "imageSku": { + "value": "[parameters('imageSku')]" + }, + "imageVersionResourceId": { + "value": "[parameters('imageVersionResourceId')]" + }, + "locationControlPlane": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location]" + }, + "locationVirtualMachines": { + "value": "[parameters('locationVirtualMachines')]" + }, + "logAnalyticsWorkspaceRetention": { + "value": "[parameters('logAnalyticsWorkspaceRetention')]" + }, + "logAnalyticsWorkspaceSku": { + "value": "[parameters('logAnalyticsWorkspaceSku')]" + }, + "maxSessionLimit": { + "value": "[mul(parameters('usersPerCore'), parameters('virtualMachineVirtualCpuCount'))]" + }, + "mlzTags": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" + }, + "namingConvention": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value]" + }, + "organizationalUnitPath": { + "value": "[parameters('organizationalUnitPath')]" + }, + "privateDnsZoneResourceIdPrefix": { + "value": "[variables('privateDnsZoneResourceIdPrefix')]" + }, + "privateDnsZones": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value]" + }, + "privateLinkScopeResourceId": { + "value": "[parameters('privateLinkScopeResourceId')]" + }, + "recoveryServices": { + "value": "[parameters('recoveryServices')]" + }, + "recoveryServicesGeo": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value.recoveryServicesGeo]" + }, + "resourceAbbreviations": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceAbbreviations.value]" + }, + "resourceGroupName": { + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'management')]" + }, + "resourceGroupProfiles": { + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'profiles')]" + }, + "securityPrincipalObjectIds": { + "value": "[map(parameters('securityPrincipals'), lambda('item', lambdaVariables('item').objectId))]" + }, + "serviceToken": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" + }, + "sessionHostNamePrefix": { + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.virtualMachine, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, '')]" + }, + "storageService": { + "value": "[variables('storageService')]" + }, + "subnetResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[0].id]" + }, + "subnets": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "timeZone": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.locationProperties.value.timeZone]" + }, + "validationEnvironment": { + "value": "[parameters('validationEnvironment')]" + }, + "virtualMachinePassword": { + "value": "[parameters('virtualMachinePassword')]" + }, + "virtualMachineSize": { + "value": "[parameters('virtualMachineSize')]" + }, + "virtualMachineUsername": { + "value": "[parameters('virtualMachineUsername')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "10495259955667653232" + } + }, + "parameters": { + "activeDirectorySolution": { + "type": "string" + }, + "avdObjectId": { + "type": "string" + }, + "avdPrivateDnsZoneResourceId": { + "type": "string" + }, + "customImageId": { + "type": "string" + }, + "customRdpProperty": { + "type": "string" + }, + "deployFslogix": { + "type": "bool" + }, + "deploymentNameSuffix": { + "type": "string" + }, + "desktopFriendlyName": { + "type": "string" + }, + "diskEncryptionSetResourceId": { + "type": "string" + }, + "diskSku": { + "type": "string" + }, + "domainJoinPassword": { + "type": "securestring" + }, + "domainJoinUserPrincipalName": { + "type": "string" + }, + "domainName": { + "type": "string" + }, + "enableApplicationInsights": { + "type": "bool" + }, + "enableAvdInsights": { + "type": "bool" + }, + "environmentAbbreviation": { + "type": "string" + }, + "fslogixStorageService": { + "type": "string" + }, + "hostPoolPublicNetworkAccess": { + "type": "string" + }, + "hostPoolType": { + "type": "string" + }, + "imageOffer": { + "type": "string" + }, + "imagePublisher": { + "type": "string" + }, + "imageSku": { + "type": "string" + }, + "imageVersionResourceId": { + "type": "string" + }, + "locationControlPlane": { + "type": "string" + }, + "locationVirtualMachines": { + "type": "string" + }, + "logAnalyticsWorkspaceRetention": { + "type": "int" + }, + "logAnalyticsWorkspaceSku": { + "type": "string" + }, + "maxSessionLimit": { + "type": "int" + }, + "mlzTags": { + "type": "object" + }, + "namingConvention": { + "type": "object" + }, + "organizationalUnitPath": { + "type": "string" + }, + "privateDnsZoneResourceIdPrefix": { + "type": "string" + }, + "privateDnsZones": { + "type": "array" + }, + "privateLinkScopeResourceId": { + "type": "string" + }, + "recoveryServices": { + "type": "bool" + }, + "recoveryServicesGeo": { + "type": "string" + }, + "resourceAbbreviations": { + "type": "object" + }, + "resourceGroupName": { + "type": "string" + }, + "resourceGroupProfiles": { + "type": "string" + }, + "securityPrincipalObjectIds": { + "type": "array" + }, + "serviceToken": { + "type": "string" + }, + "sessionHostNamePrefix": { + "type": "string" + }, + "storageService": { + "type": "string" + }, + "subnetResourceId": { + "type": "string" + }, + "subnets": { + "type": "array" + }, + "tags": { + "type": "object" + }, + "timeZone": { + "type": "string" + }, + "validationEnvironment": { + "type": "bool" + }, + "virtualMachinePassword": { + "type": "securestring" + }, + "virtualMachineSize": { + "type": "string" + }, + "virtualMachineUsername": { + "type": "string" + } + }, + "variables": { + "galleryImageOffer": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}\"', parameters('imageOffer')), 'null')]", + "galleryImagePublisher": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}\"', parameters('imagePublisher')), 'null')]", + "galleryImageSku": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}\"', parameters('imageSku')), 'null')]", + "galleryItemId": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}.{1}{2}\"', parameters('imagePublisher'), parameters('imageOffer'), parameters('imageSku')), 'null')]", + "hostPoolName": "[parameters('namingConvention').hostPool]", + "imageType": "[if(empty(parameters('imageVersionResourceId')), '\"Gallery\"', '\"CustomImage\"')]", + "userAssignedIdentityNamePrefix": "[parameters('namingConvention').userAssignedIdentity]" + }, + "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2023-07-01", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('locationControlPlane')]", + "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupName'), variables('hostPoolName'))), coalesce(tryGet(parameters('tags'), 'Microsoft.Resources/resourceGroups'), createObject()), parameters('mlzTags'))]" + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(parameters('avdObjectId'), '40c5ff49-9181-41f8-ae61-143b0e78555e', subscription().id)]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '40c5ff49-9181-41f8-ae61-143b0e78555e')]", + "principalId": "[parameters('avdObjectId')]" + } }, { - "condition": "[and(parameters('deployFslogix'), equals(parameters('fslogixStorageService'), 'AzureFiles Premium'))]", + "condition": "[or(parameters('enableApplicationInsights'), parameters('enableAvdInsights'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-function-app-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", + "name": "[format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "delegatedSubnetResourceId": { - "value": "[filter(parameters('subnets'), lambda('subnet', contains(lambdaVariables('subnet').name, 'FunctionAppOutbound')))[0].id]" - }, "deploymentNameSuffix": { "value": "[parameters('deploymentNameSuffix')]" }, - "enableApplicationInsights": { - "value": "[parameters('enableApplicationInsights')]" + "enableAvdInsights": { + "value": "[parameters('enableAvdInsights')]" }, - "environmentAbbreviation": { - "value": "[parameters('environmentAbbreviation')]" + "hostPoolResourceId": { + "value": "[format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupName'), variables('hostPoolName'))]" }, - "hostPoolName": { - "value": "[variables('hostPoolName')]" + "location": { + "value": "[parameters('locationVirtualMachines')]" }, - "logAnalyticsWorkspaceResourceId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceResourceId.value]" + "logAnalyticsWorkspaceRetention": { + "value": "[parameters('logAnalyticsWorkspaceRetention')]" }, - "namingConvention": { - "value": "[parameters('namingConvention')]" + "logAnalyticsWorkspaceSku": { + "value": "[parameters('logAnalyticsWorkspaceSku')]" }, - "privateDnsZoneResourceIdPrefix": { - "value": "[parameters('privateDnsZoneResourceIdPrefix')]" + "mlzTags": { + "value": "[parameters('mlzTags')]" }, - "privateDnsZones": { - "value": "[parameters('privateDnsZones')]" + "namingConvention": { + "value": "[parameters('namingConvention')]" }, "privateLinkScopeResourceId": { "value": "[parameters('privateLinkScopeResourceId')]" }, - "resourceAbbreviations": { - "value": "[parameters('resourceAbbreviations')]" - }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" - }, - "resourceGroupStorage": { - "value": "[parameters('resourceGroupStorage')]" - }, "serviceToken": { "value": "[parameters('serviceToken')]" }, - "subnetResourceId": { - "value": "[parameters('subnetResourceId')]" - }, "tags": { "value": "[parameters('tags')]" - }, - "timeDifference": { - "value": "[parameters('timeDifference')]" } }, "template": { @@ -8012,486 +6139,589 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "13334192291900135747" + "version": "0.31.92.45157", + "templateHash": "14902820815719387395" } }, "parameters": { - "delegatedSubnetResourceId": { - "type": "string" - }, "deploymentNameSuffix": { "type": "string" }, - "enableApplicationInsights": { + "enableAvdInsights": { "type": "bool" }, - "environmentAbbreviation": { - "type": "string" - }, - "hostPoolName": { + "hostPoolResourceId": { "type": "string" }, - "keyExpirationInDays": { - "type": "int", - "defaultValue": 30 - }, "location": { - "type": "string", - "defaultValue": "[resourceGroup().location]" - }, - "logAnalyticsWorkspaceResourceId": { "type": "string" }, - "namingConvention": { - "type": "object" + "logAnalyticsWorkspaceRetention": { + "type": "int" }, - "privateDnsZoneResourceIdPrefix": { + "logAnalyticsWorkspaceSku": { "type": "string" }, - "privateDnsZones": { - "type": "array" - }, - "privateLinkScopeResourceId": { - "type": "string" + "mlzTags": { + "type": "object" }, - "resourceAbbreviations": { + "namingConvention": { "type": "object" }, - "resourceGroupControlPlane": { + "privateLinkScopeResourceId": { "type": "string" }, - "resourceGroupStorage": { - "type": "string" + "service": { + "type": "string", + "defaultValue": "mgmt" }, "serviceToken": { "type": "string" }, - "subnetResourceId": { - "type": "string" - }, "tags": { "type": "object" - }, - "timeDifference": { - "type": "string" } }, - "variables": { - "cloudSuffix": "[replace(replace(environment().resourceManager, 'https://management.', ''), '/', '')]", - "functionAppKeyword": "[if(or(equals(environment().name, 'AzureCloud'), equals(environment().name, 'AzureUSGovernment')), 'azurewebsites', 'appservice')]", - "functionAppScmPrivateDnsZoneResourceId": "[format('{0}scm.{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), variables('functionAppKeyword'))))[0])]", - "service": "aipfsq", - "storageSubResources": [ - { - "name": "blob", - "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'blob')))[0])]", - "nic": "[parameters('namingConvention').storageAccountBlobNetworkInterface]", - "pe": "[parameters('namingConvention').storageAccountBlobPrivateEndpoint]" - }, - { - "name": "file", - "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'file')))[0])]", - "nic": "[parameters('namingConvention').storageAccountFileNetworkInterface]", - "pe": "[parameters('namingConvention').storageAccountFilePrivateEndpoint]" - }, - { - "name": "queue", - "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'queue')))[0])]", - "nic": "[parameters('namingConvention').storageAccountQueueNetworkInterface]", - "pe": "[parameters('namingConvention').storageAccountQueuePrivateEndpoint]" - }, - { - "name": "table", - "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'table')))[0])]", - "nic": "[parameters('namingConvention').storageAccountTableNetworkInterface]", - "pe": "[parameters('namingConvention').storageAccountTablePrivateEndpoint]" - } - ] - }, "resources": [ { - "type": "Microsoft.ManagedIdentity/userAssignedIdentities", - "apiVersion": "2023-01-31", - "name": "[replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))]", + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2021-06-01", + "name": "[replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service'))]", "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.ManagedIdentity/userAssignedIdentities'), createObject())]" + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.OperationalInsights/workspaces'), createObject()), parameters('mlzTags'))]", + "properties": { + "sku": { + "name": "[parameters('logAnalyticsWorkspaceSku')]" + }, + "retentionInDays": "[parameters('logAnalyticsWorkspaceRetention')]", + "workspaceCapping": { + "dailyQuotaGb": -1 + }, + "publicNetworkAccessForIngestion": "Disabled", + "publicNetworkAccessForQuery": "Enabled" + } }, { - "type": "Microsoft.KeyVault/vaults", - "apiVersion": "2022-07-01", - "name": "[format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))]", + "condition": "[parameters('enableAvdInsights')]", + "type": "Microsoft.Insights/dataCollectionRules", + "apiVersion": "2022-06-01", + "name": "[format('microsoft-avdi-{0}', replace(parameters('namingConvention').dataCollectionRule, parameters('serviceToken'), parameters('service')))]", "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.KeyVault/vaults'), createObject())]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Insights/dataCollectionRules'), createObject()), parameters('mlzTags'))]", + "kind": "Windows", "properties": { - "enabledForDeployment": false, - "enabledForDiskEncryption": false, - "enabledForTemplateDeployment": false, - "enablePurgeProtection": true, - "enableRbacAuthorization": true, - "enableSoftDelete": true, - "networkAcls": { - "bypass": "AzureServices", - "defaultAction": "Deny", - "ipRules": [], - "virtualNetworkRules": [] + "dataSources": { + "performanceCounters": [ + { + "streams": [ + "Microsoft-Perf" + ], + "samplingFrequencyInSeconds": 30, + "counterSpecifiers": [ + "\\LogicalDisk(C:)\\Avg. Disk Queue Length", + "\\LogicalDisk(C:)\\Current Disk Queue Length", + "\\Memory\\Available Mbytes", + "\\Memory\\Page Faults/sec", + "\\Memory\\Pages/sec", + "\\Memory\\% Committed Bytes In Use", + "\\PhysicalDisk(*)\\Avg. Disk Queue Length", + "\\PhysicalDisk(*)\\Avg. Disk sec/Read", + "\\PhysicalDisk(*)\\Avg. Disk sec/Transfer", + "\\PhysicalDisk(*)\\Avg. Disk sec/Write", + "\\Processor Information(_Total)\\% Processor Time", + "\\User Input Delay per Process(*)\\Max Input Delay", + "\\User Input Delay per Session(*)\\Max Input Delay", + "\\RemoteFX Network(*)\\Current TCP RTT", + "\\RemoteFX Network(*)\\Current UDP Bandwidth" + ], + "name": "perfCounterDataSource10" + }, + { + "streams": [ + "Microsoft-Perf" + ], + "samplingFrequencyInSeconds": 60, + "counterSpecifiers": [ + "\\LogicalDisk(C:)\\% Free Space", + "\\LogicalDisk(C:)\\Avg. Disk sec/Transfer", + "\\Terminal Services(*)\\Active Sessions", + "\\Terminal Services(*)\\Inactive Sessions", + "\\Terminal Services(*)\\Total Sessions" + ], + "name": "perfCounterDataSource30" + } + ], + "windowsEventLogs": [ + { + "streams": [ + "Microsoft-Event" + ], + "xPathQueries": [ + "Microsoft-Windows-TerminalServices-RemoteConnectionManager/Admin!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]", + "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]", + "System!*", + "Microsoft-FSLogix-Apps/Operational!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]", + "Application!*[System[(Level=2 or Level=3)]]", + "Microsoft-FSLogix-Apps/Admin!*[System[(Level=2 or Level=3 or Level=4 or Level=0)]]" + ], + "name": "eventLogsDataSource" + } + ] }, - "publicNetworkAccess": "Disabled", - "sku": { - "family": "A", - "name": "premium" + "destinations": { + "logAnalytics": [ + { + "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]", + "name": "la-workspace" + } + ] }, - "softDeleteRetentionInDays": "[if(or(equals(parameters('environmentAbbreviation'), 'dev'), equals(parameters('environmentAbbreviation'), 'test')), 7, 90)]", - "tenantId": "[subscription().tenantId]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2020-04-01-preview", - "scope": "[format('Microsoft.KeyVault/vaults/{0}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", - "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))), 'e147488a-f6f5-4113-8e2d-b22465e65bf6', resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))))]", - "properties": { - "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))), '2023-01-31').principalId]", - "principalType": "ServicePrincipal", - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]" + "dataFlows": [ + { + "streams": [ + "Microsoft-Perf", + "Microsoft-Event" + ], + "destinations": [ + "la-workspace" + ] + } + ] }, "dependsOn": [ - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service')))]", - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" ] }, { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "condition": "[parameters('enableAvdInsights')]", + "type": "Microsoft.Insights/dataCollectionEndpoints", + "apiVersion": "2021-04-01", + "name": "[replace(parameters('namingConvention').dataCollectionEndpoint, parameters('serviceToken'), parameters('service'))]", "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject())]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Insights/dataCollectionEndpoints'), createObject()), parameters('mlzTags'))]", + "kind": "Windows", "properties": { - "customNetworkInterfaceName": "[replace(parameters('namingConvention').keyVaultNetworkInterface, parameters('serviceToken'), variables('service'))]", - "privateLinkServiceConnections": [ - { - "name": "[replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service'))]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", - "groupIds": [ - "vault" - ] - } - } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" + "networkAcls": { + "publicNetworkAccess": "Disabled" } - }, - "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" - ] + } }, { - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2021-08-01", - "name": "[format('{0}/{1}', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')), format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-private-link-scope-law-{0}', parameters('deploymentNameSuffix'))]", + "subscriptionId": "[split(parameters('privateLinkScopeResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('privateLinkScopeResourceId'), '/')[4]]", "properties": { - "privateDnsZoneConfigs": [ - { - "name": "ipconfig1", - "properties": { - "privateDnsZoneId": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'vaultcore')))[0])]" - } + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "logAnalyticsWorkspaceResourceId": { + "value": "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" + }, + "privateLinkScopeResourceId": { + "value": "[parameters('privateLinkScopeResourceId')]" } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')))]", - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" - ] - }, - { - "type": "Microsoft.KeyVault/vaults/keys", - "apiVersion": "2022-07-01", - "name": "[format('{0}/{1}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)), 'StorageEncryptionKey')]", - "properties": { - "attributes": { - "enabled": true }, - "keySize": 4096, - "kty": "RSA", - "rotationPolicy": { - "attributes": { - "expiryTime": "[format('P{0}D', string(parameters('keyExpirationInDays')))]" + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "6666075809401495349" + } }, - "lifetimeActions": [ + "parameters": { + "applicationInsightsResourceId": { + "type": "string", + "defaultValue": "" + }, + "dataCollectionEndpointResourceId": { + "type": "string", + "defaultValue": "" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "defaultValue": "" + }, + "privateLinkScopeResourceId": { + "type": "string" + } + }, + "resources": [ { - "action": { - "type": "Notify" - }, - "trigger": { - "timeBeforeExpiry": "P10D" + "condition": "[not(empty(parameters('applicationInsightsResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('applicationInsightsResourceId')), 'applicationInsights', split(parameters('applicationInsightsResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('applicationInsightsResourceId')]" } }, { - "action": { - "type": "Rotate" - }, - "trigger": { - "timeAfterCreate": "[format('P{0}D', string(sub(parameters('keyExpirationInDays'), 7)))]" + "condition": "[not(empty(parameters('dataCollectionEndpointResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('dataCollectionEndpointResourceId')), 'dataCollectionEndpoint', split(parameters('dataCollectionEndpointResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('dataCollectionEndpointResourceId')]" + } + }, + { + "condition": "[not(empty(parameters('logAnalyticsWorkspaceResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('logAnalyticsWorkspaceResourceId')), 'logAnalyticsWorkspace', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('logAnalyticsWorkspaceResourceId')]" } } ] } }, "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" ] }, { - "type": "Microsoft.Storage/storageAccounts", + "condition": "[parameters('enableAvdInsights')]", + "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id)]", - "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.Storage/storageAccounts'), createObject())]", - "sku": { - "name": "Standard_LRS" - }, - "kind": "StorageV2", - "identity": { - "type": "UserAssigned", - "userAssignedIdentities": { - "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))))]": {} - } - }, + "name": "[format('deploy-private-link-scope-dce-{0}', parameters('deploymentNameSuffix'))]", + "subscriptionId": "[split(parameters('privateLinkScopeResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('privateLinkScopeResourceId'), '/')[4]]", "properties": { - "accessTier": "Hot", - "allowBlobPublicAccess": false, - "allowCrossTenantReplication": false, - "allowedCopyScope": "PrivateLink", - "allowSharedKeyAccess": false, - "azureFilesIdentityBasedAuthentication": { - "directoryServiceOptions": "None" + "expressionEvaluationOptions": { + "scope": "inner" }, - "defaultToOAuthAuthentication": false, - "dnsEndpointType": "Standard", - "encryption": { - "identity": { - "userAssignedIdentity": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service')))]" + "mode": "Incremental", + "parameters": { + "dataCollectionEndpointResourceId": { + "value": "[resourceId('Microsoft.Insights/dataCollectionEndpoints', replace(parameters('namingConvention').dataCollectionEndpoint, parameters('serviceToken'), parameters('service')))]" }, - "requireInfrastructureEncryption": true, - "keyvaultproperties": { - "keyvaulturi": "[reference(resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))), '2022-07-01').vaultUri]", - "keyname": "StorageEncryptionKey" + "privateLinkScopeResourceId": { + "value": "[parameters('privateLinkScopeResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "6666075809401495349" + } }, - "services": { - "file": { - "keyType": "Account", - "enabled": true + "parameters": { + "applicationInsightsResourceId": { + "type": "string", + "defaultValue": "" }, - "table": { - "keyType": "Account", - "enabled": true + "dataCollectionEndpointResourceId": { + "type": "string", + "defaultValue": "" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "defaultValue": "" + }, + "privateLinkScopeResourceId": { + "type": "string" + } + }, + "resources": [ + { + "condition": "[not(empty(parameters('applicationInsightsResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('applicationInsightsResourceId')), 'applicationInsights', split(parameters('applicationInsightsResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('applicationInsightsResourceId')]" + } }, - "queue": { - "keyType": "Account", - "enabled": true + { + "condition": "[not(empty(parameters('dataCollectionEndpointResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('dataCollectionEndpointResourceId')), 'dataCollectionEndpoint', split(parameters('dataCollectionEndpointResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('dataCollectionEndpointResourceId')]" + } }, - "blob": { - "keyType": "Account", - "enabled": true + { + "condition": "[not(empty(parameters('logAnalyticsWorkspaceResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('logAnalyticsWorkspaceResourceId')), 'logAnalyticsWorkspace', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('logAnalyticsWorkspaceResourceId')]" + } } - }, - "keySource": "Microsoft.KeyVault" - }, - "largeFileSharesState": "Disabled", - "minimumTlsVersion": "TLS1_2", - "networkAcls": { - "bypass": "AzureServices", - "virtualNetworkRules": [], - "ipRules": [], - "defaultAction": "Deny" - }, - "publicNetworkAccess": "Disabled", - "supportsHttpsTrafficOnly": true + ] + } }, "dependsOn": [ - "[resourceId('Microsoft.KeyVault/vaults/keys', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)), 'StorageEncryptionKey')]", - "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')), format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", - "[resourceId('Microsoft.Network/privateEndpoints', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')))]", - "[extensionResourceId(resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))), 'e147488a-f6f5-4113-8e2d-b22465e65bf6', resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))))]", - "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service')))]", - "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + "[resourceId('Microsoft.Insights/dataCollectionEndpoints', replace(parameters('namingConvention').dataCollectionEndpoint, parameters('serviceToken'), parameters('service')))]" ] + } + ], + "outputs": { + "logAnalyticsWorkspaceName": { + "type": "string", + "value": "[replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service'))]" }, - { - "type": "Microsoft.Storage/storageAccounts/blobServices", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), 'default')]", - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" - ] + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "value": "[resourceId('Microsoft.OperationalInsights/workspaces', replace(parameters('namingConvention').logAnalyticsWorkspace, parameters('serviceToken'), parameters('service')))]" }, - { - "copy": { - "name": "privateEndpoints_storage", - "count": "[length(variables('storageSubResources'))]" - }, - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service'))]", - "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject())]", - "properties": { - "customNetworkInterfaceName": "[replace(variables('storageSubResources')[copyIndex()].nic, parameters('serviceToken'), variables('service'))]", - "privateLinkServiceConnections": [ - { - "name": "[replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service'))]", - "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]", - "groupIds": [ - "[variables('storageSubResources')[copyIndex()].name]" - ] - } - } - ], - "subnet": { - "id": "[parameters('subnetResourceId')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" - ] + "dataCollectionRuleResourceId": { + "type": "string", + "value": "[if(parameters('enableAvdInsights'), resourceId('Microsoft.Insights/dataCollectionRules', format('microsoft-avdi-{0}', replace(parameters('namingConvention').dataCollectionRule, parameters('serviceToken'), parameters('service')))), '')]" + } + } + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "activeDirectorySolution": { + "value": "[parameters('activeDirectorySolution')]" + }, + "avdPrivateDnsZoneResourceId": { + "value": "[parameters('avdPrivateDnsZoneResourceId')]" + }, + "customImageId": { + "value": "[parameters('customImageId')]" + }, + "customRdpProperty": { + "value": "[parameters('customRdpProperty')]" + }, + "diskSku": { + "value": "[parameters('diskSku')]" + }, + "domainName": { + "value": "[parameters('domainName')]" + }, + "enableAvdInsights": { + "value": "[parameters('enableAvdInsights')]" + }, + "galleryImageOffer": { + "value": "[variables('galleryImageOffer')]" + }, + "galleryImagePublisher": { + "value": "[variables('galleryImagePublisher')]" + }, + "galleryImageSku": { + "value": "[variables('galleryImageSku')]" + }, + "galleryItemId": { + "value": "[variables('galleryItemId')]" + }, + "hostPoolDiagnosticSettingName": { + "value": "[parameters('namingConvention').hostPoolDiagnosticSetting]" + }, + "hostPoolName": { + "value": "[variables('hostPoolName')]" + }, + "hostPoolNetworkInterfaceName": { + "value": "[parameters('namingConvention').hostPoolNetworkInterface]" + }, + "hostPoolPrivateEndpointName": { + "value": "[parameters('namingConvention').hostPoolPrivateEndpoint]" + }, + "hostPoolPublicNetworkAccess": { + "value": "[parameters('hostPoolPublicNetworkAccess')]" + }, + "hostPoolType": { + "value": "[parameters('hostPoolType')]" + }, + "imageType": { + "value": "[variables('imageType')]" + }, + "location": { + "value": "[parameters('locationControlPlane')]" + }, + "logAnalyticsWorkspaceResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceResourceId.value]" + }, + "maxSessionLimit": { + "value": "[parameters('maxSessionLimit')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "sessionHostNamePrefix": { + "value": "[parameters('sessionHostNamePrefix')]" + }, + "subnetResourceId": { + "value": "[parameters('subnetResourceId')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "validationEnvironment": { + "value": "[parameters('validationEnvironment')]" + }, + "virtualMachineSize": { + "value": "[parameters('virtualMachineSize')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "17657921580737492350" + } + }, + "parameters": { + "activeDirectorySolution": { + "type": "string" + }, + "avdPrivateDnsZoneResourceId": { + "type": "string" + }, + "customImageId": { + "type": "string" + }, + "customRdpProperty": { + "type": "string" + }, + "diskSku": { + "type": "string" + }, + "domainName": { + "type": "string" + }, + "enableAvdInsights": { + "type": "bool" + }, + "galleryImageOffer": { + "type": "string" + }, + "galleryImagePublisher": { + "type": "string" + }, + "galleryImageSku": { + "type": "string" + }, + "galleryItemId": { + "type": "string" + }, + "hostPoolDiagnosticSettingName": { + "type": "string" + }, + "hostPoolName": { + "type": "string" + }, + "hostPoolNetworkInterfaceName": { + "type": "string" + }, + "hostPoolPrivateEndpointName": { + "type": "string" + }, + "hostPoolPublicNetworkAccess": { + "type": "string" + }, + "hostPoolType": { + "type": "string" + }, + "imageType": { + "type": "string" + }, + "location": { + "type": "string" }, - { - "copy": { - "name": "privateDnsZoneGroups_storage", - "count": "[length(variables('storageSubResources'))]" - }, - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2021-08-01", - "name": "[format('{0}/{1}', replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service')), uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]", - "properties": { - "privateDnsZoneConfigs": [ - { - "name": "ipconfig1", - "properties": { - "privateDnsZoneId": "[variables('storageSubResources')[copyIndex()].id]" - } - } - ] - }, - "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service')))]", - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" - ] + "logAnalyticsWorkspaceResourceId": { + "type": "string" }, - { - "condition": "[parameters('enableApplicationInsights')]", - "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2017-05-01-preview", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), 'default')]", - "name": "[replace(parameters('namingConvention').storageAccountDiagnosticSetting, format('{0}-{1}', parameters('serviceToken'), parameters('resourceAbbreviations').storageAccounts), format('blob-{0}-scale', parameters('resourceAbbreviations').storageAccounts))]", - "properties": { - "logs": [ - { - "category": "StorageWrite", - "enabled": true - } - ], - "metrics": [ - { - "category": "Transaction", - "enabled": true - } - ], - "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.Storage/storageAccounts/blobServices', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), 'default')]" - ] + "maxSessionLimit": { + "type": "int" }, - { - "condition": "[parameters('enableApplicationInsights')]", - "type": "Microsoft.Insights/components", - "apiVersion": "2020-02-02", - "name": "[replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service'))]", - "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.Insights/components'), createObject())]", - "properties": { - "Application_Type": "web", - "publicNetworkAccessForIngestion": "Disabled", - "publicNetworkAccessForQuery": "Disabled" - }, - "kind": "web" + "mlzTags": { + "type": "object" }, - { - "type": "Microsoft.Web/serverfarms", - "apiVersion": "2023-01-01", - "name": "[replace(parameters('namingConvention').appServicePlan, parameters('serviceToken'), variables('service'))]", - "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.Web/serverfarms'), createObject())]", - "sku": { - "name": "P0v3", - "tier": "PremiumV3", - "size": "P0v3", - "family": "Pv3", - "capacity": 1 - }, - "kind": "functionapp" + "sessionHostNamePrefix": { + "type": "string" + }, + "subnetResourceId": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "time": { + "type": "string", + "defaultValue": "[utcNow('u')]" + }, + "validationEnvironment": { + "type": "bool" }, + "virtualMachineSize": { + "type": "string" + } + }, + "variables": { + "customRdpProperty_Complete": "[if(contains(parameters('activeDirectorySolution'), 'MicrosoftEntraId'), format('{0}enablerdsaadauth:i:1;', parameters('customRdpProperty')), parameters('customRdpProperty'))]" + }, + "resources": [ { - "type": "Microsoft.Web/sites", - "apiVersion": "2023-01-01", - "name": "[uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)]", + "type": "Microsoft.DesktopVirtualization/hostPools", + "apiVersion": "2023-09-05", + "name": "[parameters('hostPoolName')]", "location": "[parameters('location')]", - "tags": "[coalesce(tryGet(parameters('tags'), 'Microsoft.Web/sites'), createObject())]", - "kind": "functionapp", - "identity": { - "type": "SystemAssigned" - }, + "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, resourceGroup().name, parameters('hostPoolName'))), coalesce(tryGet(parameters('tags'), 'Microsoft.DesktopVirtualization/hostPools'), createObject()), parameters('mlzTags'))]", "properties": { - "clientAffinityEnabled": false, - "httpsOnly": true, - "publicNetworkAccess": "Disabled", - "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', replace(parameters('namingConvention').appServicePlan, parameters('serviceToken'), variables('service')))]", - "siteConfig": { - "alwaysOn": true, - "appSettings": "[union(createArray(createObject('name', 'AzureWebJobsStorage__blobServiceUri', 'value', format('https://{0}.blob.{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), environment().suffixes.storage)), createObject('name', 'AzureWebJobsStorage__credential', 'value', 'managedidentity'), createObject('name', 'AzureWebJobsStorage__queueServiceUri', 'value', format('https://{0}.queue.{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), environment().suffixes.storage)), createObject('name', 'AzureWebJobsStorage__tableServiceUri', 'value', format('https://{0}.table.{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), environment().suffixes.storage)), createObject('name', 'FUNCTIONS_EXTENSION_VERSION', 'value', '~4'), createObject('name', 'FUNCTIONS_WORKER_RUNTIME', 'value', 'powershell'), createObject('name', 'WEBSITE_LOAD_USER_PROFILE', 'value', '1'), createObject('name', 'EnvironmentName', 'value', environment().name), createObject('name', 'FileShareName', 'value', 'profile-containers'), createObject('name', 'HostPoolName', 'value', parameters('hostPoolName')), createObject('name', 'HostPoolResourceGroupName', 'value', parameters('resourceGroupControlPlane')), createObject('name', 'LogOffMessageBody', 'value', 'This session is about to be logged off. Please save your work.'), createObject('name', 'LogOffMessageTitle', 'value', 'Session Log Off'), createObject('name', 'MaintenanceTagName', 'value', 'Maintenance'), createObject('name', 'ResourceGroupName', 'value', parameters('resourceGroupStorage')), createObject('name', 'ResourceManagerUrl', 'value', if(endsWith(environment().resourceManager, '/'), environment().resourceManager, format('{0}/', environment().resourceManager))), createObject('name', 'StorageSuffix', 'value', environment().suffixes.storage), createObject('name', 'SubscriptionId', 'value', subscription().subscriptionId), createObject('name', 'TenantId', 'value', subscription().tenantId), createObject('name', 'TimeDifference', 'value', parameters('timeDifference'))), if(parameters('enableApplicationInsights'), createArray(createObject('name', 'APPLICATIONINSIGHTS_CONNECTION_STRING', 'value', reference(resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service'))), '2020-02-02').ConnectionString)), createArray()))]", - "cors": { - "allowedOrigins": [ - "[format('{0}', environment().portal)]", - "[format('https://functions-next.{0}', variables('cloudSuffix'))]", - "[format('https://functions-staging.{0}', variables('cloudSuffix'))]", - "[format('https://functions.{0}', variables('cloudSuffix'))]" - ] - }, - "ftpsState": "Disabled", - "netFrameworkVersion": "v6.0", - "powerShellVersion": "7.2", - "publicNetworkAccess": "Disabled", - "use32BitWorkerProcess": false + "customRdpProperty": "[variables('customRdpProperty_Complete')]", + "hostPoolType": "[parameters('hostPoolType')]", + "loadBalancerType": "[if(equals(parameters('hostPoolType'), 'Pooled'), 'DepthFirst', 'Persistent')]", + "maxSessionLimit": "[parameters('maxSessionLimit')]", + "personalDesktopAssignmentType": "[if(equals(parameters('hostPoolType'), 'Personal'), 'Automatic', null())]", + "preferredAppGroupType": "Desktop", + "publicNetworkAccess": "[parameters('hostPoolPublicNetworkAccess')]", + "registrationInfo": { + "expirationTime": "[dateTimeAdd(parameters('time'), 'PT2H')]", + "registrationTokenOperation": "Update" }, - "virtualNetworkSubnetId": "[parameters('delegatedSubnetResourceId')]", - "vnetContentShareEnabled": false, - "vnetRouteAllEnabled": true - }, - "dependsOn": [ - "[resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service')))]", - "[resourceId('Microsoft.Web/serverfarms', replace(parameters('namingConvention').appServicePlan, parameters('serviceToken'), variables('service')))]", - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" - ] + "startVMOnConnect": true, + "validationEnvironment": "[parameters('validationEnvironment')]", + "vmTemplate": "[format('{{\"domain\":\"{0}\",\"galleryImageOffer\":{1},\"galleryImagePublisher\":{2},\"galleryImageSKU\":{3},\"imageType\":{4},\"customImageId\":{5},\"namePrefix\":\"{6}\",\"osDiskType\":\"{7}\",\"vmSize\":{{\"id\":\"{8}\",\"cores\":null,\"ram\":null,\"rdmaEnabled\": false,\"supportsMemoryPreservingMaintenance\": true}},\"galleryItemId\":{9},\"hibernate\":false,\"diskSizeGB\":0,\"securityType\":\"TrustedLaunch\",\"secureBoot\":true,\"vTPM\":true,\"vmInfrastructureType\":\"Cloud\",\"virtualProcessorCount\":null,\"memoryGB\":null,\"maximumMemoryGB\":null,\"minimumMemoryGB\":null,\"dynamicMemoryConfig\":false}}', parameters('domainName'), parameters('galleryImageOffer'), parameters('galleryImagePublisher'), parameters('galleryImageSku'), parameters('imageType'), parameters('customImageId'), parameters('sessionHostNamePrefix'), parameters('diskSku'), parameters('virtualMachineSize'), parameters('galleryItemId'))]" + } }, { "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", - "name": "[replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "name": "[parameters('hostPoolPrivateEndpointName')]", "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", "properties": { - "customNetworkInterfaceName": "[replace(parameters('namingConvention').functionAppNetworkInterface, parameters('serviceToken'), variables('service'))]", + "customNetworkInterfaceName": "[parameters('hostPoolNetworkInterfaceName')]", "privateLinkServiceConnections": [ { - "name": "[replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "name": "[parameters('hostPoolPrivateEndpointName')]", "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]", + "privateLinkServiceId": "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]", "groupIds": [ - "sites" + "connection" ] } } @@ -8501,256 +6731,274 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]" + "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" ] }, { "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2021-08-01", - "name": "[format('{0}/{1}', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')), 'default')]", + "apiVersion": "2023-05-01", + "name": "[format('{0}/{1}', parameters('hostPoolPrivateEndpointName'), 'default')]", "properties": { "privateDnsZoneConfigs": [ { - "name": "ipconfig1", + "name": "[replace(split(parameters('avdPrivateDnsZoneResourceId'), '/')[8], '.', '-')]", "properties": { - "privateDnsZoneId": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), variables('functionAppKeyword'))))[0])]" + "privateDnsZoneId": "[parameters('avdPrivateDnsZoneResourceId')]" } } ] }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')))]" + "[resourceId('Microsoft.Network/privateEndpoints', parameters('hostPoolPrivateEndpointName'))]" ] }, { - "condition": "[parameters('enableApplicationInsights')]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-private-link-scope-appi-{0}', parameters('deploymentNameSuffix'))]", - "subscriptionId": "[split(parameters('privateLinkScopeResourceId'), '/')[2]]", - "resourceGroup": "[split(parameters('privateLinkScopeResourceId'), '/')[4]]", + "condition": "[parameters('enableAvdInsights')]", + "type": "Microsoft.Insights/diagnosticSettings", + "apiVersion": "2021-05-01-preview", + "scope": "[format('Microsoft.DesktopVirtualization/hostPools/{0}', parameters('hostPoolName'))]", + "name": "[parameters('hostPoolDiagnosticSettingName')]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "applicationInsightsResourceId": { - "value": "[resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service')))]" - }, - "privateLinkScopeResourceId": { - "value": "[parameters('privateLinkScopeResourceId')]" + "logs": [ + { + "categoryGroup": "allLogs", + "enabled": true } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "8149225552603313421" - } - }, - "parameters": { - "applicationInsightsResourceId": { - "type": "string", - "defaultValue": "" - }, - "dataCollectionEndpointResourceId": { - "type": "string", - "defaultValue": "" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "defaultValue": "" - }, - "privateLinkScopeResourceId": { - "type": "string" - } - }, - "resources": [ - { - "condition": "[not(empty(parameters('applicationInsightsResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('applicationInsightsResourceId')), 'applicationInsights', split(parameters('applicationInsightsResourceId'), '/')[8]))]", - "properties": { - "linkedResourceId": "[parameters('applicationInsightsResourceId')]" - } - }, - { - "condition": "[not(empty(parameters('dataCollectionEndpointResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('dataCollectionEndpointResourceId')), 'dataCollectionEndpoint', split(parameters('dataCollectionEndpointResourceId'), '/')[8]))]", - "properties": { - "linkedResourceId": "[parameters('dataCollectionEndpointResourceId')]" - } - }, - { - "condition": "[not(empty(parameters('logAnalyticsWorkspaceResourceId')))]", - "type": "Microsoft.Insights/privateLinkScopes/scopedResources", - "apiVersion": "2021-09-01", - "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('logAnalyticsWorkspaceResourceId')), 'logAnalyticsWorkspace', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]))]", - "properties": { - "linkedResourceId": "[parameters('logAnalyticsWorkspaceResourceId')]" - } - } - ] - } + ], + "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]" }, "dependsOn": [ - "[resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service')))]" + "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" ] + } + ], + "outputs": { + "name": { + "type": "string", + "value": "[parameters('hostPoolName')]" + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-disk-access-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "hostPoolResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "location": { + "value": "[parameters('locationVirtualMachines')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "namingConvention": { + "value": "[parameters('namingConvention')]" + }, + "subnetResourceId": { + "value": "[parameters('subnetResourceId')]" + }, + "tags": { + "value": "[parameters('tags')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "3145769776971011079" + } + }, + "parameters": { + "hostPoolResourceId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" }, + "namingConvention": { + "type": "object" + }, + "subnetResourceId": { + "type": "string" + }, + "tags": { + "type": "object" + } + }, + "resources": [ { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('set-role-assignment-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupStorage')]", + "type": "Microsoft.Compute/diskAccesses", + "apiVersion": "2021-04-01", + "name": "[parameters('namingConvention').diskAccess]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/diskAccesses'), createObject()), parameters('mlzTags'))]", + "properties": {} + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('namingConvention').diskAccessPrivateEndpoint]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "principalId": { - "value": "[reference(resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)), '2023-01-01', 'full').identity.principalId]" - }, - "principalType": { - "value": "ServicePrincipal" - }, - "roleDefinitionId": { - "value": "17d1049b-9a84-46fb-8f53-869881c3d3ab" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1315528727979495191" - } - }, - "parameters": { - "principalId": { - "type": "string" - }, - "principalType": { - "type": "string" - }, - "roleDefinitionId": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", - "principalId": "[parameters('principalId')]", - "principalType": "[parameters('principalType')]" - } + "customNetworkInterfaceName": "[parameters('namingConvention').diskAccessNetworkInterface]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('namingConvention').diskAccessPrivateEndpoint]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Compute/diskAccesses', parameters('namingConvention').diskAccess)]", + "groupIds": [ + "disks" + ] } - ] + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" } }, "dependsOn": [ - "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]" + "[resourceId('Microsoft.Compute/diskAccesses', parameters('namingConvention').diskAccess)]" ] + } + ], + "outputs": { + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Compute/diskAccesses', parameters('namingConvention').diskAccess)]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-policy-disks-{0}', parameters('deploymentNameSuffix'))]", + "location": "[deployment().location]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "diskAccessResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-disk-access-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "location": { + "value": "[parameters('locationControlPlane')]" + }, + "resourceGroupName": { + "value": "[parameters('resourceGroupName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "6736401548874707618" + } + }, + "parameters": { + "diskAccessResourceId": { + "type": "string", + "defaultValue": "" + }, + "location": { + "type": "string" }, + "resourceGroupName": { + "type": "string" + } + }, + "variables": { + "parameters": "[if(not(empty(parameters('diskAccessResourceId'))), createObject('diskAccessId', createObject('type', 'String', 'metadata', createObject('displayName', 'Disk Access Resource Id', 'description', 'The resource Id of the Disk Access to associate to the managed disks.'))), createObject())]", + "operations": "[if(not(empty(parameters('diskAccessResourceId'))), createArray(createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/networkAccessPolicy', 'value', 'AllowPrivate'), createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/publicNetworkAccess', 'value', 'Disabled'), createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/diskAccessId', 'value', '[parameters(''diskAccessId'')]')), createArray(createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/networkAccessPolicy', 'value', 'DenyAll'), createObject('operation', 'addOrReplace', 'field', 'Microsoft.Compute/disks/publicNetworkAccess', 'value', 'Disabled')))]" + }, + "resources": [ { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('set-role-assignment-storage-{0}', parameters('deploymentNameSuffix'))]", + "type": "Microsoft.Authorization/policyDefinitions", + "apiVersion": "2021-06-01", + "name": "DiskNetworkAccess", "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "principalId": { - "value": "[reference(resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)), '2023-01-01', 'full').identity.principalId]" - }, - "principalType": { - "value": "ServicePrincipal" - }, - "roleDefinitionId": { - "value": "b7e6dc6d-f1e8-4753-8033-0f276bb0955b" - }, - "storageAccountName": { - "value": "[uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id)]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6271853608623957112" - } - }, - "parameters": { - "principalId": { - "type": "string" - }, - "principalType": { - "type": "string" - }, - "roleDefinitionId": { - "type": "string" - }, - "storageAccountName": { - "type": "string" - } + "description": "Disable network access to managed disks.", + "displayName": "Disable Disk Access", + "mode": "All", + "parameters": "[variables('parameters')]", + "policyRule": { + "if": { + "field": "type", + "equals": "Microsoft.Compute/disks" }, - "resources": [ - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('storageAccountName'))]", - "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", - "principalId": "[parameters('principalId')]", - "principalType": "[parameters('principalType')]" - } + "then": { + "effect": "modify", + "details": { + "roleDefinitionIds": [ + "/providers/Microsoft.Authorization/roleDefinitions/60fc6e62-5479-42d4-8bf4-67625fcc2840" + ], + "operations": "[variables('operations')]" } - ] - } - }, - "dependsOn": [ - "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]", - "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" - ] + } + }, + "policyType": "Custom" + } }, { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-scm-a-record-{0}', parameters('deploymentNameSuffix'))]", - "subscriptionId": "[split(variables('functionAppScmPrivateDnsZoneResourceId'), '/')[2]]", - "resourceGroup": "[split(variables('functionAppScmPrivateDnsZoneResourceId'), '/')[4]]", + "name": "assign-policy-disk-network-access", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "functionAppName": { - "value": "[uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)]" + "diskAccessResourceId": { + "value": "[parameters('diskAccessResourceId')]" }, - "ipv4Address": { - "value": "[filter(reference(resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')), 'default'), '2021-08-01').privateDnsZoneConfigs[0].properties.recordSets, lambda('record', equals(lambdaVariables('record').recordSetName, uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))))[0].ipAddresses[0]]" + "location": { + "value": "[parameters('location')]" }, - "privateDnsZoneName": { - "value": "[split(variables('functionAppScmPrivateDnsZoneResourceId'), '/')[8]]" + "policyDefinitionId": { + "value": "[subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess')]" + }, + "policyDisplayName": { + "value": "[reference(subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess'), '2021-06-01').displayName]" + }, + "policyName": { + "value": "[reference(subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess'), '2021-06-01').displayName]" } }, "template": { @@ -8759,112 +7007,264 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "9646048614586675609" + "version": "0.31.92.45157", + "templateHash": "1275953978872597894" } }, "parameters": { - "functionAppName": { + "diskAccessResourceId": { "type": "string" }, - "ipv4Address": { + "location": { "type": "string" }, - "privateDnsZoneName": { + "policyDefinitionId": { + "type": "string" + }, + "policyDisplayName": { + "type": "string" + }, + "policyName": { "type": "string" } }, "resources": [ { - "type": "Microsoft.Network/privateDnsZones/A", - "apiVersion": "2020-06-01", - "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('functionAppName'))]", + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2022-06-01", + "name": "[parameters('policyName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, "properties": { - "aRecords": [ - { - "ipv4Address": "[parameters('ipv4Address')]" - } - ], - "ttl": 3600 + "displayName": "[parameters('policyDisplayName')]", + "policyDefinitionId": "[parameters('policyDefinitionId')]", + "parameters": "[if(not(empty(parameters('diskAccessResourceId'))), createObject('diskAccessId', createObject('value', parameters('diskAccessResourceId'))), createObject())]" } } ] } }, "dependsOn": [ - "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]", - "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')), 'default')]" + "[subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess')]" ] } ], "outputs": { - "functionAppName": { + "policyDefinitionId": { "type": "string", - "value": "[uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)]" + "value": "[subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess')]" + }, + "policyDisplayName": { + "type": "string", + "value": "[reference(subscriptionResourceId('Microsoft.Authorization/policyDefinitions', 'DiskNetworkAccess'), '2021-06-01').displayName]" } } } }, "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix')))]" + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-disk-access-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" ] }, { - "condition": "[parameters('recoveryServices')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-rsv-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", + "name": "[format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "azureBlobsPrivateDnsZoneResourceId": { - "value": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'blob')))[0])]" + "location": { + "value": "[parameters('locationVirtualMachines')]" }, - "azureQueueStoragePrivateDnsZoneResourceId": { - "value": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'queue')))[0])]" + "name": { + "value": "[replace(variables('userAssignedIdentityNamePrefix'), parameters('serviceToken'), 'deployment')]" }, - "deployFslogix": { - "value": "[parameters('deployFslogix')]" + "tags": { + "value": "[union(createObject('cm-resource-parent', reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value), coalesce(tryGet(parameters('tags'), 'Microsoft.ManagedIdentity/userAssignedIdentities'), createObject()), parameters('mlzTags'))]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "10766099399924390355" + } }, - "hostPoolName": { - "value": "[variables('hostPoolName')]" + "parameters": { + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "object" + } }, - "location": { - "value": "[parameters('locationVirtualMachines')]" + "resources": [ + { + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2018-11-30", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]" + } + ], + "outputs": { + "clientId": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')), '2018-11-30').clientId]" + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name'))]" + }, + "principalId": { + "type": "string", + "value": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('name')), '2018-11-30').principalId]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('assign-role-mgmt-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "principalId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" }, - "mlzTags": { - "value": "[parameters('mlzTags')]" + "principalType": { + "value": "ServicePrincipal" }, - "recoveryServicesPrivateDnsZoneResourceId": { - "value": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', startsWith(lambdaVariables('name'), format('privatelink.{0}.backup.windowsazure', parameters('recoveryServicesGeo')))))[0])]" + "roleDefinitionId": { + "value": "082f0a83-3be5-4ba1-904c-961cca79b387" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "10174155731090308034" + } }, - "recoveryServicesVaultName": { - "value": "[parameters('namingConvention').recoveryServicesVault]" + "parameters": { + "principalId": { + "type": "string" + }, + "principalType": { + "type": "string" + }, + "roleDefinitionId": { + "type": "string" + } }, - "recoveryServicesVaultNetworkInterfaceName": { - "value": "[parameters('namingConvention').recoveryServicesVaultNetworkInterface]" + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", + "principalId": "[parameters('principalId')]", + "principalType": "[parameters('principalType')]" + } + } + ] + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "deploymentUserAssignedIdentityPrincipalId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" }, - "recoveryServicesVaultPrivateEndpointName": { - "value": "[parameters('namingConvention').recoveryServicesVaultPrivateEndpoint]" + "deploymentUserAssignedIdentityResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" + "diskEncryptionSetResourceId": { + "value": "[parameters('diskEncryptionSetResourceId')]" }, - "storageService": { - "value": "[parameters('storageService')]" + "diskName": { + "value": "[replace(parameters('namingConvention').virtualMachineDisk, parameters('serviceToken'), 'mgt')]" + }, + "diskSku": { + "value": "[parameters('diskSku')]" + }, + "domainJoinPassword": { + "value": "[parameters('domainJoinPassword')]" + }, + "domainJoinUserPrincipalName": { + "value": "[parameters('domainJoinUserPrincipalName')]" + }, + "domainName": { + "value": "[parameters('domainName')]" + }, + "hostPoolResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "location": { + "value": "[parameters('locationVirtualMachines')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "networkInterfaceName": { + "value": "[replace(parameters('namingConvention').virtualMachineNetworkInterface, parameters('serviceToken'), 'mgt')]" }, - "subnetId": { + "organizationalUnitPath": { + "value": "[parameters('organizationalUnitPath')]" + }, + "subnetResourceId": { "value": "[parameters('subnetResourceId')]" }, "tags": { "value": "[parameters('tags')]" }, - "timeZone": { - "value": "[parameters('timeZone')]" + "virtualMachineName": { + "value": "[replace(parameters('namingConvention').virtualMachine, parameters('serviceToken'), 'mgt')]" + }, + "virtualMachinePassword": { + "value": "[parameters('virtualMachinePassword')]" + }, + "virtualMachineUsername": { + "value": "[parameters('virtualMachineUsername')]" } }, "template": { @@ -8873,590 +7273,874 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "12830230504350465325" + "version": "0.31.92.45157", + "templateHash": "3320903441430575822" } }, "parameters": { - "azureBlobsPrivateDnsZoneResourceId": { + "deploymentUserAssignedIdentityPrincipalId": { "type": "string" }, - "azureQueueStoragePrivateDnsZoneResourceId": { + "deploymentUserAssignedIdentityResourceId": { "type": "string" }, - "deployFslogix": { - "type": "bool" + "diskEncryptionSetResourceId": { + "type": "string" }, - "hostPoolName": { + "diskName": { "type": "string" }, - "location": { + "diskSku": { "type": "string" }, - "mlzTags": { - "type": "object" + "domainJoinPassword": { + "type": "securestring" }, - "recoveryServicesPrivateDnsZoneResourceId": { + "domainJoinUserPrincipalName": { "type": "string" }, - "recoveryServicesVaultName": { + "domainName": { "type": "string" }, - "recoveryServicesVaultNetworkInterfaceName": { + "hostPoolResourceId": { "type": "string" }, - "recoveryServicesVaultPrivateEndpointName": { + "location": { "type": "string" }, - "resourceGroupControlPlane": { + "mlzTags": { + "type": "object" + }, + "networkInterfaceName": { "type": "string" }, - "storageService": { + "organizationalUnitPath": { "type": "string" }, - "subnetId": { + "subnetResourceId": { "type": "string" }, "tags": { "type": "object" }, - "timeZone": { + "timestamp": { + "type": "string", + "defaultValue": "[utcNow('yyyyMMddhhmmss')]" + }, + "virtualMachineName": { + "type": "string" + }, + "virtualMachinePassword": { + "type": "securestring" + }, + "virtualMachineUsername": { "type": "string" } }, + "variables": { + "tagsVirtualMachines": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/virtualMachines'), createObject()), parameters('mlzTags'))]" + }, "resources": [ { - "type": "Microsoft.RecoveryServices/vaults", - "apiVersion": "2022-03-01", - "name": "[parameters('recoveryServicesVaultName')]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.RecoveryServices/vaults'), parameters('tags')['Microsoft.RecoveryServices/vaults'], createObject()), parameters('mlzTags'))]", - "sku": { - "name": "RS0", - "tier": "Standard" - }, - "properties": {} - }, - { - "condition": "[and(parameters('deployFslogix'), equals(parameters('storageService'), 'AzureFiles'))]", - "type": "Microsoft.RecoveryServices/vaults/backupPolicies", - "apiVersion": "2022-03-01", - "name": "[format('{0}/{1}', parameters('recoveryServicesVaultName'), 'AvdPolicyStorage')]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.RecoveryServices/vaults'), parameters('tags')['Microsoft.RecoveryServices/vaults'], createObject()), parameters('mlzTags'))]", - "properties": { - "backupManagementType": "AzureStorage", - "schedulePolicy": { - "scheduleRunFrequency": "Daily", - "scheduleRunTimes": [ - "23:00" - ], - "schedulePolicyType": "SimpleSchedulePolicy" - }, - "retentionPolicy": { - "retentionPolicyType": "LongTermRetentionPolicy", - "dailySchedule": { - "retentionTimes": [ - "23:00" - ], - "retentionDuration": { - "count": 30, - "durationType": "Days" - } - } - }, - "timeZone": "[parameters('timeZone')]", - "workLoadType": "AzureFileShare" - }, - "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" - ] - }, - { - "condition": "[not(parameters('deployFslogix'))]", - "type": "Microsoft.RecoveryServices/vaults/backupPolicies", - "apiVersion": "2022-03-01", - "name": "[format('{0}/{1}', parameters('recoveryServicesVaultName'), 'AvdPolicyVm')]", - "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.RecoveryServices/vaults'), parameters('tags')['Microsoft.RecoveryServices/vaults'], createObject()), parameters('mlzTags'))]", - "properties": { - "backupManagementType": "AzureIaasVM", - "instantRpRetentionRangeInDays": 2, - "policyType": "V2", - "retentionPolicy": { - "retentionPolicyType": "LongTermRetentionPolicy", - "dailySchedule": { - "retentionTimes": [ - "23:00" - ], - "retentionDuration": { - "count": 30, - "durationType": "Days" - } - } - }, - "schedulePolicy": { - "schedulePolicyType": "SimpleSchedulePolicyV2", - "scheduleRunFrequency": "Daily", - "dailySchedule": { - "scheduleRunTimes": [ - "23:00" - ] - } - }, - "timeZone": "[parameters('timeZone')]" - }, - "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" - ] - }, - { - "type": "Microsoft.Network/privateEndpoints", - "apiVersion": "2023-04-01", - "name": "[parameters('recoveryServicesVaultPrivateEndpointName')]", + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2020-05-01", + "name": "[parameters('networkInterfaceName')]", "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/networkInterfaces'), createObject()), parameters('mlzTags'))]", "properties": { - "customNetworkInterfaceName": "[parameters('recoveryServicesVaultNetworkInterfaceName')]", - "privateLinkServiceConnections": [ + "ipConfigurations": [ { - "name": "[parameters('recoveryServicesVaultPrivateEndpointName')]", + "name": "ipconfig", "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]", - "groupIds": [ - "AzureBackup" - ] + "privateIPAllocationMethod": "Dynamic", + "subnet": { + "id": "[parameters('subnetResourceId')]" + }, + "primary": true, + "privateIPAddressVersion": "IPv4" } } ], - "subnet": { - "id": "[parameters('subnetId')]" - } - }, - "dependsOn": [ - "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" - ] + "enableAcceleratedNetworking": false, + "enableIPForwarding": false + } }, { - "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2021-08-01", - "name": "[format('{0}/{1}', parameters('recoveryServicesVaultPrivateEndpointName'), parameters('recoveryServicesVaultName'))]", + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2021-11-01", + "name": "[parameters('virtualMachineName')]", + "location": "[parameters('location')]", + "tags": "[variables('tagsVirtualMachines')]", "properties": { - "privateDnsZoneConfigs": [ - { - "name": "[replace(parameters('recoveryServicesPrivateDnsZoneResourceId'), '.', '-')]", - "properties": { - "privateDnsZoneId": "[parameters('recoveryServicesPrivateDnsZoneResourceId')]" - } + "hardwareProfile": { + "vmSize": "Standard_B2s" + }, + "storageProfile": { + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2019-datacenter-core-g2", + "version": "latest" }, - { - "name": "[replace(parameters('azureQueueStoragePrivateDnsZoneResourceId'), '.', '-')]", - "properties": { - "privateDnsZoneId": "[parameters('azureQueueStoragePrivateDnsZoneResourceId')]" - } + "osDisk": { + "deleteOption": "Delete", + "osType": "Windows", + "createOption": "FromImage", + "caching": "None", + "managedDisk": { + "diskEncryptionSet": { + "id": "[parameters('diskEncryptionSetResourceId')]" + }, + "storageAccountType": "[parameters('diskSku')]" + }, + "name": "[parameters('diskName')]" }, - { - "name": "[replace(parameters('azureBlobsPrivateDnsZoneResourceId'), '.', '-')]", - "properties": { - "privateDnsZoneId": "[parameters('azureBlobsPrivateDnsZoneResourceId')]" + "dataDisks": [] + }, + "osProfile": { + "computerName": "[parameters('virtualMachineName')]", + "adminUsername": "[parameters('virtualMachineUsername')]", + "adminPassword": "[parameters('virtualMachinePassword')]", + "windowsConfiguration": { + "provisionVMAgent": true, + "enableAutomaticUpdates": false + }, + "secrets": [], + "allowExtensionOperations": true + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]", + "properties": { + "deleteOption": "Delete" + } } + ] + }, + "securityProfile": { + "uefiSettings": { + "secureBootEnabled": true, + "vTpmEnabled": true + }, + "securityType": "TrustedLaunch", + "encryptionAtHost": true + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": false } - ] + }, + "licenseType": "Windows_Server" + }, + "identity": { + "type": "SystemAssigned, UserAssigned", + "userAssignedIdentities": { + "[format('{0}', parameters('deploymentUserAssignedIdentityResourceId'))]": {} + } }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('recoveryServicesVaultPrivateEndpointName'))]", - "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" - ] - } - ], - "outputs": { - "name": { - "type": "string", - "value": "[parameters('recoveryServicesVaultName')]" - } - } - } - } - } - ], - "outputs": { - "dataCollectionRuleResourceId": { - "type": "string", - "value": "[if(parameters('enableAvdInsights'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.dataCollectionRuleResourceId.value, '')]" - }, - "deploymentUserAssignedIdentityClientId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.clientId.value]" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" - }, - "deploymentUserAssignedIdentityResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - }, - "functionAppName": { - "type": "string", - "value": "[if(equals(parameters('fslogixStorageService'), 'AzureFiles Premium'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-function-app-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.functionAppName.value, '')]" - }, - "logAnalyticsWorkspaceName": { - "type": "string", - "value": "[if(or(parameters('enableApplicationInsights'), parameters('enableAvdInsights')), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceName.value, '')]" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string", - "value": "[if(or(parameters('enableApplicationInsights'), parameters('enableAvdInsights')), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceResourceId.value, '')]" - }, - "recoveryServicesVaultName": { - "type": "string", - "value": "[if(parameters('recoveryServices'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-rsv-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value, '')]" - }, - "virtualMachineName": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "virtualMachineResourceId": { - "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - } - } - } - }, - "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[0], parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[1], parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix')))]" - ] - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-control-plane-{0}', parameters('deploymentNameSuffix'))]", - "location": "[deployment().location]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "activeDirectorySolution": { - "value": "[parameters('activeDirectorySolution')]" - }, - "avdPrivateDnsZoneResourceId": { - "value": "[format('{0}{1}', variables('privateDnsZoneResourceIdPrefix'), filter(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value, lambda('name', startsWith(lambdaVariables('name'), 'privatelink.wvd')))[0])]" - }, - "customImageId": { - "value": "[variables('customImageId')]" - }, - "customRdpProperty": { - "value": "[parameters('customRdpProperty')]" - }, - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "deploymentUserAssignedIdentityClientId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.deploymentUserAssignedIdentityClientId.value]" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.deploymentUserAssignedIdentityPrincipalId.value]" - }, - "desktopFriendlyName": "[if(empty(parameters('desktopFriendlyName')), createObject('value', string(parameters('stampIndex'))), createObject('value', parameters('desktopFriendlyName')))]", - "diskSku": { - "value": "[parameters('diskSku')]" - }, - "domainName": { - "value": "[parameters('domainName')]" - }, - "enableAvdInsights": { - "value": "[parameters('enableAvdInsights')]" - }, - "hostPoolPublicNetworkAccess": { - "value": "[parameters('hostPoolPublicNetworkAccess')]" - }, - "hostPoolType": { - "value": "[parameters('hostPoolType')]" - }, - "imageOffer": { - "value": "[parameters('imageOffer')]" - }, - "imagePublisher": { - "value": "[parameters('imagePublisher')]" - }, - "imageSku": { - "value": "[parameters('imageSku')]" - }, - "imageVersionResourceId": { - "value": "[parameters('imageVersionResourceId')]" - }, - "locationControlPlane": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location]" - }, - "locationVirtualMachines": { - "value": "[parameters('locationVirtualMachines')]" - }, - "logAnalyticsWorkspaceResourceId": "[if(parameters('enableAvdInsights'), createObject('value', reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceResourceId.value), createObject('value', ''))]", - "managementVirtualMachineName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.virtualMachineName.value]" - }, - "maxSessionLimit": { - "value": "[mul(parameters('usersPerCore'), parameters('virtualMachineVirtualCpuCount'))]" - }, - "mlzTags": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" - }, - "namingConvention": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value]" - }, - "resourceGroupControlPlane": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[0], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "resourceGroupManagement": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "roleDefinitions": { - "value": "[variables('roleDefinitions')]" - }, - "securityPrincipalObjectIds": { - "value": "[map(parameters('securityPrincipals'), lambda('item', lambdaVariables('item').objectId))]" - }, - "serviceToken": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service]" - }, - "sessionHostNamePrefix": { - "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.virtualMachine, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, '')]" - }, - "subnetResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.subnets.value[1].id]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "validationEnvironment": { - "value": "[parameters('validationEnvironment')]" - }, - "virtualMachineSize": { - "value": "[parameters('virtualMachineSize')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "16583821302504592892" - } - }, - "parameters": { - "activeDirectorySolution": { - "type": "string" - }, - "avdPrivateDnsZoneResourceId": { - "type": "string" - }, - "customImageId": { - "type": "string" - }, - "customRdpProperty": { - "type": "string" - }, - "deploymentNameSuffix": { - "type": "string" - }, - "deploymentUserAssignedIdentityClientId": { - "type": "string" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "type": "string" - }, - "desktopFriendlyName": { - "type": "string" - }, - "diskSku": { - "type": "string" - }, - "domainName": { - "type": "string" - }, - "enableAvdInsights": { - "type": "bool" - }, - "hostPoolPublicNetworkAccess": { - "type": "string" - }, - "hostPoolType": { - "type": "string" - }, - "imageOffer": { - "type": "string" - }, - "imagePublisher": { - "type": "string" - }, - "imageSku": { - "type": "string" - }, - "imageVersionResourceId": { - "type": "string" - }, - "locationControlPlane": { - "type": "string" - }, - "locationVirtualMachines": { - "type": "string" - }, - "logAnalyticsWorkspaceResourceId": { - "type": "string" - }, - "managementVirtualMachineName": { - "type": "string" - }, - "maxSessionLimit": { - "type": "int" - }, - "mlzTags": { - "type": "object" - }, - "namingConvention": { - "type": "object" - }, - "resourceGroupControlPlane": { - "type": "string" - }, - "resourceGroupManagement": { - "type": "string" - }, - "roleDefinitions": { - "type": "object" - }, - "securityPrincipalObjectIds": { - "type": "array" - }, - "serviceToken": { - "type": "string" - }, - "sessionHostNamePrefix": { - "type": "string" - }, - "subnetResourceId": { - "type": "string" + "[resourceId('Microsoft.Network/networkInterfaces', parameters('networkInterfaceName'))]" + ] + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2021-03-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), 'IaaSAntimalware')]", + "location": "[parameters('location')]", + "tags": "[variables('tagsVirtualMachines')]", + "properties": { + "publisher": "Microsoft.Azure.Security", + "type": "IaaSAntimalware", + "typeHandlerVersion": "1.3", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": false, + "settings": { + "AntimalwareEnabled": true, + "RealtimeProtectionEnabled": "true", + "ScheduledScanSettings": { + "isEnabled": "true", + "day": "7", + "time": "120", + "scanType": "Quick" + }, + "Exclusions": {} + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" + ] + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2021-03-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), 'GuestAttestation')]", + "location": "[parameters('location')]", + "properties": { + "publisher": "Microsoft.Azure.Security.WindowsAttestation", + "type": "GuestAttestation", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "settings": { + "AttestationConfig": { + "MaaSettings": { + "maaEndpoint": "", + "maaTenantName": "GuestAttestation" + }, + "AscSettings": { + "ascReportingEndpoint": "", + "ascReportingFrequency": "" + }, + "useCustomToken": "false", + "disableAlerts": "false" + } + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" + ] + }, + { + "type": "Microsoft.Compute/virtualMachines/extensions", + "apiVersion": "2019-07-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), 'JsonADDomainExtension')]", + "location": "[parameters('location')]", + "tags": "[variables('tagsVirtualMachines')]", + "properties": { + "forceUpdateTag": "[parameters('timestamp')]", + "publisher": "Microsoft.Compute", + "type": "JsonADDomainExtension", + "typeHandlerVersion": "1.3", + "autoUpgradeMinorVersion": true, + "settings": { + "Name": "[parameters('domainName')]", + "Options": "3", + "OUPath": "[parameters('organizationalUnitPath')]", + "Restart": "true", + "User": "[parameters('domainJoinUserPrincipalName')]" + }, + "protectedSettings": { + "Password": "[parameters('domainJoinPassword')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" + ] + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Compute/virtualMachines/{0}', parameters('virtualMachineName'))]", + "name": "[guid(parameters('deploymentUserAssignedIdentityPrincipalId'), 'a959dbd1-f747-45e3-8ba6-dd80f235f97c', resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName')))]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'a959dbd1-f747-45e3-8ba6-dd80f235f97c')]", + "principalId": "[parameters('deploymentUserAssignedIdentityPrincipalId')]", + "principalType": "ServicePrincipal" + }, + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" + ] + } + ], + "outputs": { + "name": { + "type": "string", + "value": "[parameters('virtualMachineName')]" + }, + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix')))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] }, - "tags": { - "type": "object" + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-vdag-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" + }, + "deploymentUserAssignedIdentityClientId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.clientId.value]" + }, + "desktopApplicationGroupName": { + "value": "[parameters('namingConvention').applicationGroup]" + }, + "hostPoolResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "locationControlPlane": { + "value": "[parameters('locationControlPlane')]" + }, + "locationVirtualMachines": { + "value": "[parameters('locationVirtualMachines')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "securityPrincipalObjectIds": { + "value": "[parameters('securityPrincipalObjectIds')]" + }, + "desktopFriendlyName": { + "value": "[parameters('desktopFriendlyName')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "virtualMachineName": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "15585962471976115155" + } + }, + "parameters": { + "deploymentNameSuffix": { + "type": "string" + }, + "deploymentUserAssignedIdentityClientId": { + "type": "string" + }, + "desktopApplicationGroupName": { + "type": "string" + }, + "desktopFriendlyName": { + "type": "string" + }, + "hostPoolResourceId": { + "type": "string" + }, + "locationControlPlane": { + "type": "string" + }, + "locationVirtualMachines": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "securityPrincipalObjectIds": { + "type": "array" + }, + "tags": { + "type": "object" + }, + "virtualMachineName": { + "type": "string" + } + }, + "variables": { + "$fxv#0": "Param(\r\n [string]$ApplicationGroupName,\r\n [string]$FriendlyName,\r\n [string]$ResourceGroupName,\r\n [string]$ResourceManagerUri,\r\n [string]$SubscriptionId,\r\n [string]$UserAssignedIdentityClientId\r\n)\r\n\r\n$ErrorActionPreference = 'Stop'\r\n$WarningPreference = 'SilentlyContinue'\r\n\r\n# Wait for role assignment propagation\r\nStart-Sleep -Seconds 30\r\n\r\n# Fix the resource manager URI since only AzureCloud contains a trailing slash\r\n$ResourceManagerUriFixed = if ($ResourceManagerUri[-1] -eq '/') {$ResourceManagerUri} else {$ResourceManagerUri + '/'}\r\n\r\n# Get an access token for Azure resources\r\n$AzureManagementAccessToken = (Invoke-RestMethod `\r\n -Headers @{Metadata=\"true\"} `\r\n -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token\r\n\r\n# Set header for Azure Management API\r\n$AzureManagementHeader = @{\r\n 'Content-Type'='application/json'\r\n 'Authorization'='Bearer ' + $AzureManagementAccessToken\r\n}\r\n\r\n# Update the friendly name on the session desktop\r\nInvoke-RestMethod `\r\n -Body (@{properties = @{friendlyName = $FriendlyName.Replace('\"', '')}} | ConvertTo-Json) `\r\n -Headers $AzureManagementHeader `\r\n -Method 'PATCH' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/applicationGroups/' + $ApplicationGroupName + '/desktops/SessionDesktop?api-version=2022-02-10-preview') | Out-Null" + }, + "resources": [ + { + "type": "Microsoft.DesktopVirtualization/applicationGroups", + "apiVersion": "2023-09-05", + "name": "[parameters('desktopApplicationGroupName')]", + "location": "[parameters('locationControlPlane')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.DesktopVirtualization/applicationGroups'), createObject()), parameters('mlzTags'))]", + "properties": { + "hostPoolArmPath": "[parameters('hostPoolResourceId')]", + "applicationGroupType": "Desktop" + } + }, + { + "copy": { + "name": "roleAssignment_ApplicationGroup", + "count": "[length(range(0, length(parameters('securityPrincipalObjectIds'))))]" + }, + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.DesktopVirtualization/applicationGroups/{0}', parameters('desktopApplicationGroupName'))]", + "name": "[guid(parameters('securityPrincipalObjectIds')[range(0, length(parameters('securityPrincipalObjectIds')))[copyIndex()]], '1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63', resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName')))]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '1d18fff3-a72a-46b5-b4a9-0b38a3cd7e63')]", + "principalId": "[parameters('securityPrincipalObjectIds')[range(0, length(parameters('securityPrincipalObjectIds')))[copyIndex()]]]" + }, + "dependsOn": [ + "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]" + ] + }, + { + "condition": "[not(empty(parameters('desktopFriendlyName')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-vdapp-friendly-name-{0}', parameters('deploymentNameSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('locationVirtualMachines')]" + }, + "name": { + "value": "Update-AvdDesktop" + }, + "parameters": { + "value": [ + { + "name": "ApplicationGroupName", + "value": "[parameters('desktopApplicationGroupName')]" + }, + { + "name": "FriendlyName", + "value": "[parameters('desktopFriendlyName')]" + }, + { + "name": "ResourceGroupName", + "value": "[resourceGroup().name]" + }, + { + "name": "ResourceManagerUri", + "value": "[environment().resourceManager]" + }, + { + "name": "SubscriptionId", + "value": "[subscription().subscriptionId]" + }, + { + "name": "UserAssignedIdentityClientId", + "value": "[parameters('deploymentUserAssignedIdentityClientId')]" + } + ] + }, + "script": { + "value": "[variables('$fxv#0')]" + }, + "tags": { + "value": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/virtualMachines'), createObject()), parameters('mlzTags'))]" + }, + "virtualMachineName": { + "value": "[parameters('virtualMachineName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" + } + }, + "parameters": { + "asyncExecution": { + "type": "bool", + "defaultValue": false + }, + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parameters": { + "type": "array", + "defaultValue": [] + }, + "script": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "treatFailureAsDeploymentFailure": { + "type": "bool", + "defaultValue": true + }, + "virtualMachineName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Compute/virtualMachines/runCommands", + "apiVersion": "2023-09-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "asyncExecution": "[parameters('asyncExecution')]", + "parameters": "[parameters('parameters')]", + "source": { + "script": "[parameters('script')]" + }, + "treatFailureAsDeploymentFailure": "[parameters('treatFailureAsDeploymentFailure')]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]" + ] + } + ], + "outputs": { + "resourceId": { + "type": "string", + "value": "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix')))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix')))]" + ] }, - "validationEnvironment": { - "type": "bool" + { + "condition": "[parameters('recoveryServices')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-rsv-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "azureBlobsPrivateDnsZoneResourceId": { + "value": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'blob')))[0])]" + }, + "azureQueueStoragePrivateDnsZoneResourceId": { + "value": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'queue')))[0])]" + }, + "deployFslogix": { + "value": "[parameters('deployFslogix')]" + }, + "hostPoolResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "location": { + "value": "[parameters('locationVirtualMachines')]" + }, + "mlzTags": { + "value": "[parameters('mlzTags')]" + }, + "recoveryServicesPrivateDnsZoneResourceId": { + "value": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', startsWith(lambdaVariables('name'), format('privatelink.{0}.backup.windowsazure', parameters('recoveryServicesGeo')))))[0])]" + }, + "recoveryServicesVaultName": { + "value": "[parameters('namingConvention').recoveryServicesVault]" + }, + "recoveryServicesVaultNetworkInterfaceName": { + "value": "[parameters('namingConvention').recoveryServicesVaultNetworkInterface]" + }, + "recoveryServicesVaultPrivateEndpointName": { + "value": "[parameters('namingConvention').recoveryServicesVaultPrivateEndpoint]" + }, + "storageService": { + "value": "[parameters('storageService')]" + }, + "subnetId": { + "value": "[parameters('subnetResourceId')]" + }, + "tags": { + "value": "[parameters('tags')]" + }, + "timeZone": { + "value": "[parameters('timeZone')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "15719775133926232352" + } + }, + "parameters": { + "azureBlobsPrivateDnsZoneResourceId": { + "type": "string" + }, + "azureQueueStoragePrivateDnsZoneResourceId": { + "type": "string" + }, + "deployFslogix": { + "type": "bool" + }, + "hostPoolResourceId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "mlzTags": { + "type": "object" + }, + "recoveryServicesPrivateDnsZoneResourceId": { + "type": "string" + }, + "recoveryServicesVaultName": { + "type": "string" + }, + "recoveryServicesVaultNetworkInterfaceName": { + "type": "string" + }, + "recoveryServicesVaultPrivateEndpointName": { + "type": "string" + }, + "storageService": { + "type": "string" + }, + "subnetId": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "timeZone": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.RecoveryServices/vaults", + "apiVersion": "2022-03-01", + "name": "[parameters('recoveryServicesVaultName')]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.RecoveryServices/vaults'), createObject()), parameters('mlzTags'))]", + "sku": { + "name": "RS0", + "tier": "Standard" + }, + "properties": {} + }, + { + "condition": "[and(parameters('deployFslogix'), equals(parameters('storageService'), 'AzureFiles'))]", + "type": "Microsoft.RecoveryServices/vaults/backupPolicies", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('recoveryServicesVaultName'), 'AvdPolicyStorage')]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.RecoveryServices/vaults'), createObject()), parameters('mlzTags'))]", + "properties": { + "backupManagementType": "AzureStorage", + "schedulePolicy": { + "scheduleRunFrequency": "Daily", + "scheduleRunTimes": [ + "23:00" + ], + "schedulePolicyType": "SimpleSchedulePolicy" + }, + "retentionPolicy": { + "retentionPolicyType": "LongTermRetentionPolicy", + "dailySchedule": { + "retentionTimes": [ + "23:00" + ], + "retentionDuration": { + "count": 30, + "durationType": "Days" + } + } + }, + "timeZone": "[parameters('timeZone')]", + "workLoadType": "AzureFileShare" + }, + "dependsOn": [ + "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" + ] + }, + { + "condition": "[not(parameters('deployFslogix'))]", + "type": "Microsoft.RecoveryServices/vaults/backupPolicies", + "apiVersion": "2022-03-01", + "name": "[format('{0}/{1}', parameters('recoveryServicesVaultName'), 'AvdPolicyVm')]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.RecoveryServices/vaults'), createObject()), parameters('mlzTags'))]", + "properties": { + "backupManagementType": "AzureIaasVM", + "instantRpRetentionRangeInDays": 2, + "policyType": "V2", + "retentionPolicy": { + "retentionPolicyType": "LongTermRetentionPolicy", + "dailySchedule": { + "retentionTimes": [ + "23:00" + ], + "retentionDuration": { + "count": 30, + "durationType": "Days" + } + } + }, + "schedulePolicy": { + "schedulePolicyType": "SimpleSchedulePolicyV2", + "scheduleRunFrequency": "Daily", + "dailySchedule": { + "scheduleRunTimes": [ + "23:00" + ] + } + }, + "timeZone": "[parameters('timeZone')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[parameters('recoveryServicesVaultPrivateEndpointName')]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", + "properties": { + "customNetworkInterfaceName": "[parameters('recoveryServicesVaultNetworkInterfaceName')]", + "privateLinkServiceConnections": [ + { + "name": "[parameters('recoveryServicesVaultPrivateEndpointName')]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]", + "groupIds": [ + "AzureBackup" + ] + } + } + ], + "subnet": { + "id": "[parameters('subnetId')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2021-08-01", + "name": "[format('{0}/{1}', parameters('recoveryServicesVaultPrivateEndpointName'), parameters('recoveryServicesVaultName'))]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "[replace(parameters('recoveryServicesPrivateDnsZoneResourceId'), '.', '-')]", + "properties": { + "privateDnsZoneId": "[parameters('recoveryServicesPrivateDnsZoneResourceId')]" + } + }, + { + "name": "[replace(parameters('azureQueueStoragePrivateDnsZoneResourceId'), '.', '-')]", + "properties": { + "privateDnsZoneId": "[parameters('azureQueueStoragePrivateDnsZoneResourceId')]" + } + }, + { + "name": "[replace(parameters('azureBlobsPrivateDnsZoneResourceId'), '.', '-')]", + "properties": { + "privateDnsZoneId": "[parameters('azureBlobsPrivateDnsZoneResourceId')]" + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', parameters('recoveryServicesVaultPrivateEndpointName'))]", + "[resourceId('Microsoft.RecoveryServices/vaults', parameters('recoveryServicesVaultName'))]" + ] + } + ], + "outputs": { + "name": { + "type": "string", + "value": "[parameters('recoveryServicesVaultName')]" + } + } + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] }, - "virtualMachineSize": { - "type": "string" - } - }, - "variables": { - "galleryImageOffer": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}\"', parameters('imageOffer')), 'null')]", - "galleryImagePublisher": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}\"', parameters('imagePublisher')), 'null')]", - "galleryImageSku": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}\"', parameters('imageSku')), 'null')]", - "galleryItemId": "[if(empty(parameters('imageVersionResourceId')), format('\"{0}.{1}{2}\"', parameters('imagePublisher'), parameters('imageOffer'), parameters('imageSku')), 'null')]", - "hostPoolName": "[parameters('namingConvention').hostPool]", - "imageType": "[if(empty(parameters('imageVersionResourceId')), '\"Gallery\"', '\"CustomImage\"')]" - }, - "resources": [ { + "condition": "[equals(parameters('fslogixStorageService'), 'AzureFiles Premium')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupControlPlane')]", + "name": "[format('deploy-function-app-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "activeDirectorySolution": { - "value": "[parameters('activeDirectorySolution')]" - }, - "avdPrivateDnsZoneResourceId": { - "value": "[parameters('avdPrivateDnsZoneResourceId')]" - }, - "customImageId": { - "value": "[parameters('customImageId')]" - }, - "customRdpProperty": { - "value": "[parameters('customRdpProperty')]" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "value": "[parameters('deploymentUserAssignedIdentityPrincipalId')]" - }, - "diskSku": { - "value": "[parameters('diskSku')]" - }, - "domainName": { - "value": "[parameters('domainName')]" - }, - "enableAvdInsights": { - "value": "[parameters('enableAvdInsights')]" - }, - "galleryImageOffer": { - "value": "[variables('galleryImageOffer')]" - }, - "galleryImagePublisher": { - "value": "[variables('galleryImagePublisher')]" - }, - "galleryImageSku": { - "value": "[variables('galleryImageSku')]" + "delegatedSubnetResourceId": { + "value": "[filter(parameters('subnets'), lambda('subnet', contains(lambdaVariables('subnet').name, 'FunctionAppOutbound')))[0].id]" }, - "galleryItemId": { - "value": "[variables('galleryItemId')]" + "deploymentNameSuffix": { + "value": "[parameters('deploymentNameSuffix')]" }, - "hostPoolDiagnosticSettingName": { - "value": "[parameters('namingConvention').hostPoolDiagnosticSetting]" + "enableApplicationInsights": { + "value": "[parameters('enableApplicationInsights')]" }, - "hostPoolName": { - "value": "[variables('hostPoolName')]" + "environmentAbbreviation": { + "value": "[parameters('environmentAbbreviation')]" }, - "hostPoolNetworkInterfaceName": { - "value": "[parameters('namingConvention').hostPoolNetworkInterface]" + "hostPoolResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" }, - "hostPoolPrivateEndpointName": { - "value": "[parameters('namingConvention').hostPoolPrivateEndpoint]" + "logAnalyticsWorkspaceResourceId": { + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceResourceId.value]" }, - "hostPoolPublicNetworkAccess": { - "value": "[parameters('hostPoolPublicNetworkAccess')]" + "mlzTags": { + "value": "[parameters('mlzTags')]" }, - "hostPoolType": { - "value": "[parameters('hostPoolType')]" + "namingConvention": { + "value": "[parameters('namingConvention')]" }, - "imageType": { - "value": "[variables('imageType')]" + "privateDnsZoneResourceIdPrefix": { + "value": "[parameters('privateDnsZoneResourceIdPrefix')]" }, - "location": { - "value": "[parameters('locationControlPlane')]" + "privateDnsZones": { + "value": "[parameters('privateDnsZones')]" }, - "logAnalyticsWorkspaceResourceId": { - "value": "[parameters('logAnalyticsWorkspaceResourceId')]" + "privateLinkScopeResourceId": { + "value": "[parameters('privateLinkScopeResourceId')]" }, - "maxSessionLimit": { - "value": "[parameters('maxSessionLimit')]" + "resourceAbbreviations": { + "value": "[parameters('resourceAbbreviations')]" }, - "mlzTags": { - "value": "[parameters('mlzTags')]" + "resourceGroupProfiles": { + "value": "[parameters('resourceGroupProfiles')]" }, - "sessionHostNamePrefix": { - "value": "[parameters('sessionHostNamePrefix')]" + "serviceToken": { + "value": "[parameters('serviceToken')]" }, "subnetResourceId": { "value": "[parameters('subnetResourceId')]" }, "tags": { "value": "[parameters('tags')]" - }, - "validationEnvironment": { - "value": "[parameters('validationEnvironment')]" - }, - "virtualMachineSize": { - "value": "[parameters('virtualMachineSize')]" } }, "template": { @@ -9465,142 +8149,341 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "9719336724197777662" + "version": "0.31.92.45157", + "templateHash": "1960226860650229376" } }, "parameters": { - "activeDirectorySolution": { - "type": "string" - }, - "avdPrivateDnsZoneResourceId": { - "type": "string" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "type": "string" - }, - "customImageId": { - "type": "string" - }, - "customRdpProperty": { - "type": "string" - }, - "diskSku": { + "delegatedSubnetResourceId": { "type": "string" }, - "domainName": { + "deploymentNameSuffix": { "type": "string" }, - "enableAvdInsights": { + "enableApplicationInsights": { "type": "bool" }, - "galleryImageOffer": { - "type": "string" - }, - "galleryImagePublisher": { - "type": "string" - }, - "galleryImageSku": { - "type": "string" - }, - "galleryItemId": { - "type": "string" - }, - "hostPoolDiagnosticSettingName": { - "type": "string" - }, - "hostPoolName": { - "type": "string" - }, - "hostPoolNetworkInterfaceName": { - "type": "string" - }, - "hostPoolPrivateEndpointName": { - "type": "string" - }, - "hostPoolPublicNetworkAccess": { + "environmentAbbreviation": { "type": "string" }, - "hostPoolType": { + "hostPoolResourceId": { "type": "string" }, - "imageType": { - "type": "string" + "keyExpirationInDays": { + "type": "int", + "defaultValue": 30 }, "location": { - "type": "string" + "type": "string", + "defaultValue": "[resourceGroup().location]" }, "logAnalyticsWorkspaceResourceId": { "type": "string" }, - "maxSessionLimit": { - "type": "int" - }, "mlzTags": { "type": "object" }, - "sessionHostNamePrefix": { + "namingConvention": { + "type": "object" + }, + "privateDnsZoneResourceIdPrefix": { "type": "string" }, - "subnetResourceId": { + "privateDnsZones": { + "type": "array" + }, + "privateLinkScopeResourceId": { "type": "string" }, - "tags": { + "resourceAbbreviations": { "type": "object" }, - "time": { - "type": "string", - "defaultValue": "[utcNow('u')]" + "resourceGroupProfiles": { + "type": "string" }, - "validationEnvironment": { - "type": "bool" + "serviceToken": { + "type": "string" }, - "virtualMachineSize": { + "subnetResourceId": { "type": "string" + }, + "tags": { + "type": "object" } }, "variables": { - "customRdpProperty_Complete": "[if(contains(parameters('activeDirectorySolution'), 'MicrosoftEntraId'), format('{0}enablerdsaadauth:i:1;', parameters('customRdpProperty')), parameters('customRdpProperty'))]" + "$fxv#0": "# This file enables modules to be automatically managed by the Functions service.\r\n# See https://aka.ms/functionsmanageddependency for additional information.\r\n#\r\n@{\r\n # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'. \r\n # To use the Az module in your function app, please uncomment the line below.\r\n # 'Az' = '7.*'\r\n}", + "$fxv#1": "param($Timer)\r\n\r\ntry\r\n{\r\n\t[string]$FileShareName = $env:FileShareName\r\n\t[string]$ResourceGroupName = $env:ResourceGroupName\r\n\t[string]$ResourceManagerUrl = $env:ResourceManagerUrl\r\n\t[string]$StorageSuffix = $env:StorageSuffix\r\n\t[string]$SubscriptionId = $env:SubscriptionId\r\n\r\n\t$ErrorActionPreference = 'Stop'\r\n\t$WarningPreference = 'SilentlyContinue'\r\n\r\n\t#region Functions\r\n\tfunction Write-Log \r\n {\r\n\t\t[CmdletBinding()]\r\n\t\tparam (\r\n\t\t\t[Parameter(Mandatory = $false)]\r\n\t\t\t[switch]$Err,\r\n\r\n\t\t\t[Parameter(Mandatory = $true)]\r\n\t\t\t[string]$Message,\r\n\r\n\t\t\t[Parameter(Mandatory = $true)]\r\n\t\t\t[string]$ResourceName,\r\n\r\n\t\t\t[Parameter(Mandatory = $false)]\r\n\t\t\t[switch]$Warn\r\n\t\t)\r\n\r\n\t\t[string]$MessageTimeStamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'\r\n\t\t$Message = \"[$($MyInvocation.ScriptLineNumber)] [$($ResourceName)] $Message\"\r\n\t\t[string]$WriteMessage = \"[$($MessageTimeStamp)] $Message\"\r\n\r\n\t\tif ($Err)\r\n {\r\n\t\t\tWrite-Error $WriteMessage\r\n\t\t\t$Message = \"ERROR: $Message\"\r\n\t\t}\r\n\t\telseif ($Warn)\r\n {\r\n\t\t\tWrite-Warning $WriteMessage\r\n\t\t\t$Message = \"WARN: $Message\"\r\n\t\t}\r\n\t\telse \r\n {\r\n\t\t\tWrite-Output $WriteMessage\r\n\t\t}\r\n\t}\r\n\t#endregion Functions\r\n\r\n\t# Note: https://stackoverflow.com/questions/41674518/powershell-setting-security-protocol-to-tls-1-2\r\n\t[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\r\n\r\n\r\n\t#region Azure Authentication\r\n $AccessToken = $null\r\n try\r\n {\r\n\t\t$TokenAuthURI = $env:IDENTITY_ENDPOINT + '?resource=' + $ResourceManagerUrl + '&api-version=2019-08-01'\r\n\t\t$TokenResponse = Invoke-RestMethod -Method Get -Headers @{\"X-IDENTITY-HEADER\"=\"$env:IDENTITY_HEADER\"} -Uri $TokenAuthURI\r\n\t\t$AccessToken = $TokenResponse.access_token\r\n\t\t$Header = @{\r\n\t\t\t'Content-Type'='application/json'\r\n\t\t\t'Authorization'='Bearer ' + $AccessToken\r\n\t\t}\r\n }\r\n catch\r\n {\r\n throw [System.Exception]::new('Failed to authenticate Azure with application ID, tenant ID, subscription ID', $PSItem.Exception)\r\n }\r\n Write-Log -ResourceName \"$SubscriptionId\" -Message \"Successfully authenticated with Azure using a managed identity\"\r\n\t#endregion Azure Authentication\r\n\r\n\t# Get storage accounts\r\n\t$Uri = $ResourceManagerUrl + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.Storage/storageAccounts?api-version=2023-05-01'\r\n\t$StorageAccountNames = (Invoke-RestMethod -Headers $Header -Method 'GET' -Uri $Uri).value.name\r\n\r\n\tforeach($StorageAccountName in $StorageAccountNames)\r\n\t{\r\n\t\t$ShareUpdateUri = $ResourceManagerUrl + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/fileServices/default/shares/' + $FileShareName + '?api-version=2023-05-01'\r\n\r\n\t\t# Get file share info\r\n\t\t$ShareGetUri = $ResourceManagerUrl + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/fileServices/default/shares/' + $FileShareName + '?api-version=2023-05-01&$expand=stats'\r\n\t\t$PFS = (Invoke-RestMethod -Headers $Header -Method 'GET' -Uri $ShareGetUri).properties\r\n\r\n\t\t# Set variables for provisioned capacity and used capacity\r\n\t\t$ProvisionedCapacity = $PFS.shareQuota\r\n\t\t$UsedCapacity = $PFS.ShareUsageBytes\r\n\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Capacity: $($ProvisionedCapacity)GB\"\r\n\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage: $([math]::Round($UsedCapacity/1GB, 0))GB\"\r\n\r\n\t\t# GB Based Scaling\r\n\t\t# No scaling if no usage\r\n\t\tif($UsedCapacity -eq 0)\r\n\t\t{\r\n\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage is 0GB. No Changes.\"\r\n\t\t}\r\n\t\t# Slow scaling up to 500GB\r\n\t\t# Increases share quota by 100GB if less than 50GB remains on the share\r\n\t\t# This allows time for an AVD Stamp to be rolled out \r\n\t\telseif ($ProvisionedCapacity -lt 500)\r\n\t\t{\r\n\t\t\tif (($ProvisionedCapacity - ($UsedCapacity / ([Math]::Pow(2,30)))) -lt 50) {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage has surpassed the Share Quota remaining threshold of 50GB. Increasing the file share quota by 100GB.\" \r\n\t\t\t\t$Quota = $ProvisionedCapacity + 100\r\n\t\t\t\tInvoke-RestMethod `\r\n\t\t\t\t\t-Body (@{properties = @{shareQuota = $Quota}} | ConvertTo-Json) `\r\n\t\t\t\t\t-Headers $Header `\r\n\t\t\t\t\t-Method 'PATCH' `\r\n\t\t\t\t\t-Uri $ShareUpdateUri | Out-Null\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"New Capacity: $($Quota)GB\"\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage is below Share Quota remaining threshold of 50GB. No Changes.\"\r\n\t\t\t}\r\n\t\t}\r\n\t\t# Aggressive scaling\r\n\t\t# Increases share quota by 500GB if less than 500GB remains on the share\r\n\t\t# This ensures plenty of space is available during mass onboarding\r\n\t\telse \r\n\t\t{\r\n\t\t\tif (($ProvisionedCapacity - ($UsedCapacity / ([Math]::Pow(2,30)))) -lt 500) {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage has surpassed the Share Quota remaining threshold of 500GB. Increasing the file share quota by 500GB.\" \r\n\t\t\t\t$Quota = $ProvisionedCapacity + 500\r\n\t\t\t\tInvoke-RestMethod `\r\n\t\t\t\t\t-Body (@{properties = @{shareQuota = $Quota}} | ConvertTo-Json) `\r\n\t\t\t\t\t-Headers $Header `\r\n\t\t\t\t\t-Method 'PATCH' `\r\n\t\t\t\t\t-Uri $ShareUpdateUri | Out-Null\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"New Capacity: $($Quota)GB\"\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage is below Share Quota remaining threshold of 500GB. No Changes.\"\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\ncatch \r\n{\r\n\t$ErrContainer = $PSItem\r\n\t# $ErrContainer = $_\r\n\r\n\t[string]$ErrMsg = $ErrContainer | Format-List -Force | Out-String\r\n\t$ErrMsg += \"Version: $Version`n\"\r\n\r\n\tif (Get-Command 'Write-Log' -ErrorAction:SilentlyContinue)\r\n {\r\n\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Err -Message $ErrMsg -ErrorAction:Continue\r\n\t}\r\n\telse\r\n {\r\n\t\tWrite-Error $ErrMsg -ErrorAction:Continue\r\n\t}\r\n\r\n\tthrow [System.Exception]::new($ErrMsg, $ErrContainer.Exception)\r\n}", + "$fxv#2": "# Authentication is provided in the script", + "cloudSuffix": "[replace(replace(environment().resourceManager, 'https://management.', ''), '/', '')]", + "functionAppKeyword": "[if(or(equals(environment().name, 'AzureCloud'), equals(environment().name, 'AzureUSGovernment')), 'azurewebsites', 'appservice')]", + "functionAppScmPrivateDnsZoneResourceId": "[format('{0}scm.{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), variables('functionAppKeyword'))))[0])]", + "service": "aipfsq", + "storageSubResources": [ + { + "name": "blob", + "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'blob')))[0])]", + "nic": "[parameters('namingConvention').storageAccountBlobNetworkInterface]", + "pe": "[parameters('namingConvention').storageAccountBlobPrivateEndpoint]" + }, + { + "name": "file", + "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'file')))[0])]", + "nic": "[parameters('namingConvention').storageAccountFileNetworkInterface]", + "pe": "[parameters('namingConvention').storageAccountFilePrivateEndpoint]" + }, + { + "name": "queue", + "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'queue')))[0])]", + "nic": "[parameters('namingConvention').storageAccountQueueNetworkInterface]", + "pe": "[parameters('namingConvention').storageAccountQueuePrivateEndpoint]" + }, + { + "name": "table", + "id": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'table')))[0])]", + "nic": "[parameters('namingConvention').storageAccountTableNetworkInterface]", + "pe": "[parameters('namingConvention').storageAccountTablePrivateEndpoint]" + } + ] }, "resources": [ { - "type": "Microsoft.DesktopVirtualization/hostPools", - "apiVersion": "2023-09-05", - "name": "[parameters('hostPoolName')]", + "type": "Microsoft.ManagedIdentity/userAssignedIdentities", + "apiVersion": "2023-01-31", + "name": "[replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.ManagedIdentity/userAssignedIdentities'), createObject()), parameters('mlzTags'))]" + }, + { + "type": "Microsoft.KeyVault/vaults", + "apiVersion": "2022-07-01", + "name": "[format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))]", "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, resourceGroup().name, parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.DesktopVirtualization/hostPools'), parameters('tags')['Microsoft.DesktopVirtualization/hostPools'], createObject()), parameters('mlzTags'))]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.KeyVault/vaults'), createObject()), parameters('mlzTags'))]", "properties": { - "customRdpProperty": "[variables('customRdpProperty_Complete')]", - "hostPoolType": "[parameters('hostPoolType')]", - "loadBalancerType": "[if(equals(parameters('hostPoolType'), 'Pooled'), 'DepthFirst', 'Persistent')]", - "maxSessionLimit": "[parameters('maxSessionLimit')]", - "personalDesktopAssignmentType": "[if(equals(parameters('hostPoolType'), 'Personal'), 'Automatic', null())]", - "preferredAppGroupType": "Desktop", - "publicNetworkAccess": "[parameters('hostPoolPublicNetworkAccess')]", - "registrationInfo": { - "expirationTime": "[dateTimeAdd(parameters('time'), 'PT2H')]", - "registrationTokenOperation": "Update" + "enabledForDeployment": false, + "enabledForDiskEncryption": false, + "enabledForTemplateDeployment": false, + "enablePurgeProtection": true, + "enableRbacAuthorization": true, + "enableSoftDelete": true, + "networkAcls": { + "bypass": "AzureServices", + "defaultAction": "Deny", + "ipRules": [], + "virtualNetworkRules": [] + }, + "publicNetworkAccess": "Disabled", + "sku": { + "family": "A", + "name": "premium" + }, + "softDeleteRetentionInDays": "[if(or(equals(parameters('environmentAbbreviation'), 'dev'), equals(parameters('environmentAbbreviation'), 'test')), 7, 90)]", + "tenantId": "[subscription().tenantId]" + } + }, + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2020-04-01-preview", + "scope": "[format('Microsoft.KeyVault/vaults/{0}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", + "name": "[guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))), 'e147488a-f6f5-4113-8e2d-b22465e65bf6', resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))))]", + "properties": { + "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))), '2023-01-31').principalId]", + "principalType": "ServicePrincipal", + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', 'e147488a-f6f5-4113-8e2d-b22465e65bf6')]" + }, + "dependsOn": [ + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service')))]", + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", + "properties": { + "customNetworkInterfaceName": "[replace(parameters('namingConvention').keyVaultNetworkInterface, parameters('serviceToken'), variables('service'))]", + "privateLinkServiceConnections": [ + { + "name": "[replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", + "groupIds": [ + "vault" + ] + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2021-08-01", + "name": "[format('{0}/{1}', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')), format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", + "properties": { + "privateDnsZoneConfigs": [ + { + "name": "ipconfig1", + "properties": { + "privateDnsZoneId": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), 'vaultcore')))[0])]" + } + } + ] + }, + "dependsOn": [ + "[resourceId('Microsoft.Network/privateEndpoints', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')))]", + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/keys", + "apiVersion": "2022-07-01", + "name": "[format('{0}/{1}', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)), 'StorageEncryptionKey')]", + "properties": { + "attributes": { + "enabled": true + }, + "keySize": 4096, + "kty": "RSA", + "rotationPolicy": { + "attributes": { + "expiryTime": "[format('P{0}D', string(parameters('keyExpirationInDays')))]" + }, + "lifetimeActions": [ + { + "action": { + "type": "Notify" + }, + "trigger": { + "timeBeforeExpiry": "P10D" + } + }, + { + "action": { + "type": "Rotate" + }, + "trigger": { + "timeAfterCreate": "[format('P{0}D', string(sub(parameters('keyExpirationInDays'), 7)))]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2022-09-01", + "name": "[uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id)]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Storage/storageAccounts'), createObject()), parameters('mlzTags'))]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[format('{0}', resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))))]": {} + } + }, + "properties": { + "accessTier": "Hot", + "allowBlobPublicAccess": false, + "allowCrossTenantReplication": false, + "allowedCopyScope": "PrivateLink", + "allowSharedKeyAccess": false, + "azureFilesIdentityBasedAuthentication": { + "directoryServiceOptions": "None" + }, + "defaultToOAuthAuthentication": false, + "dnsEndpointType": "Standard", + "encryption": { + "identity": { + "userAssignedIdentity": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service')))]" + }, + "requireInfrastructureEncryption": true, + "keyvaultproperties": { + "keyvaulturi": "[reference(resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))), '2022-07-01').vaultUri]", + "keyname": "StorageEncryptionKey" + }, + "services": { + "file": { + "keyType": "Account", + "enabled": true + }, + "table": { + "keyType": "Account", + "enabled": true + }, + "queue": { + "keyType": "Account", + "enabled": true + }, + "blob": { + "keyType": "Account", + "enabled": true + } + }, + "keySource": "Microsoft.KeyVault" }, - "startVMOnConnect": true, - "validationEnvironment": "[parameters('validationEnvironment')]", - "vmTemplate": "[format('{{\"domain\":\"{0}\",\"galleryImageOffer\":{1},\"galleryImagePublisher\":{2},\"galleryImageSKU\":{3},\"imageType\":{4},\"customImageId\":{5},\"namePrefix\":\"{6}\",\"osDiskType\":\"{7}\",\"vmSize\":{{\"id\":\"{8}\",\"cores\":null,\"ram\":null,\"rdmaEnabled\": false,\"supportsMemoryPreservingMaintenance\": true}},\"galleryItemId\":{9},\"hibernate\":false,\"diskSizeGB\":0,\"securityType\":\"TrustedLaunch\",\"secureBoot\":true,\"vTPM\":true,\"vmInfrastructureType\":\"Cloud\",\"virtualProcessorCount\":null,\"memoryGB\":null,\"maximumMemoryGB\":null,\"minimumMemoryGB\":null,\"dynamicMemoryConfig\":false}}', parameters('domainName'), parameters('galleryImageOffer'), parameters('galleryImagePublisher'), parameters('galleryImageSku'), parameters('imageType'), parameters('customImageId'), parameters('sessionHostNamePrefix'), parameters('diskSku'), parameters('virtualMachineSize'), parameters('galleryItemId'))]" - } + "largeFileSharesState": "Disabled", + "minimumTlsVersion": "TLS1_2", + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Deny" + }, + "publicNetworkAccess": "Disabled", + "supportsHttpsTrafficOnly": true + }, + "dependsOn": [ + "[resourceId('Microsoft.KeyVault/vaults/keys', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)), 'StorageEncryptionKey')]", + "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')), format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]", + "[resourceId('Microsoft.Network/privateEndpoints', replace(parameters('namingConvention').keyVaultPrivateEndpoint, parameters('serviceToken'), variables('service')))]", + "[extensionResourceId(resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id))), 'Microsoft.Authorization/roleAssignments', guid(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service'))), 'e147488a-f6f5-4113-8e2d-b22465e65bf6', resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))))]", + "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', replace(parameters('namingConvention').userAssignedIdentity, parameters('serviceToken'), variables('service')))]", + "[resourceId('Microsoft.KeyVault/vaults', format('{0}{1}', parameters('resourceAbbreviations').keyVaults, uniqueString(replace(parameters('namingConvention').keyVault, parameters('serviceToken'), variables('service')), resourceGroup().id)))]" + ] + }, + { + "type": "Microsoft.Storage/storageAccounts/blobServices", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), 'default')]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" + ] }, { + "copy": { + "name": "privateEndpoints_storage", + "count": "[length(variables('storageSubResources'))]" + }, "type": "Microsoft.Network/privateEndpoints", "apiVersion": "2023-04-01", - "name": "[parameters('hostPoolPrivateEndpointName')]", + "name": "[replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service'))]", "location": "[parameters('location')]", - "tags": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, resourceGroup().name, parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", "properties": { - "customNetworkInterfaceName": "[parameters('hostPoolNetworkInterfaceName')]", + "customNetworkInterfaceName": "[replace(variables('storageSubResources')[copyIndex()].nic, parameters('serviceToken'), variables('service'))]", "privateLinkServiceConnections": [ { - "name": "[parameters('hostPoolPrivateEndpointName')]", + "name": "[replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service'))]", "properties": { - "privateLinkServiceId": "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]", + "privateLinkServiceId": "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]", "groupIds": [ - "connection" + "[variables('storageSubResources')[copyIndex()].name]" ] } } @@ -9610,282 +8493,368 @@ } }, "dependsOn": [ - "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" ] }, { + "copy": { + "name": "privateDnsZoneGroups_storage", + "count": "[length(variables('storageSubResources'))]" + }, "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", - "apiVersion": "2023-05-01", - "name": "[format('{0}/{1}', parameters('hostPoolPrivateEndpointName'), 'default')]", + "apiVersion": "2021-08-01", + "name": "[format('{0}/{1}', replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service')), uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]", "properties": { "privateDnsZoneConfigs": [ { - "name": "[replace(split(parameters('avdPrivateDnsZoneResourceId'), '/')[8], '.', '-')]", + "name": "ipconfig1", "properties": { - "privateDnsZoneId": "[parameters('avdPrivateDnsZoneResourceId')]" + "privateDnsZoneId": "[variables('storageSubResources')[copyIndex()].id]" } } ] }, "dependsOn": [ - "[resourceId('Microsoft.Network/privateEndpoints', parameters('hostPoolPrivateEndpointName'))]" - ] - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.DesktopVirtualization/hostPools/{0}', parameters('hostPoolName'))]", - "name": "[guid(parameters('deploymentUserAssignedIdentityPrincipalId'), '2ad6aaab-ead9-4eaa-8ac5-da422f562408', resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName')))]", - "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '2ad6aaab-ead9-4eaa-8ac5-da422f562408')]", - "principalId": "[parameters('deploymentUserAssignedIdentityPrincipalId')]", - "principalType": "ServicePrincipal" - }, - "dependsOn": [ - "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" + "[resourceId('Microsoft.Network/privateEndpoints', replace(variables('storageSubResources')[copyIndex()].pe, parameters('serviceToken'), variables('service')))]", + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" ] }, { - "condition": "[parameters('enableAvdInsights')]", + "condition": "[parameters('enableApplicationInsights')]", "type": "Microsoft.Insights/diagnosticSettings", - "apiVersion": "2021-05-01-preview", - "scope": "[format('Microsoft.DesktopVirtualization/hostPools/{0}', parameters('hostPoolName'))]", - "name": "[parameters('hostPoolDiagnosticSettingName')]", + "apiVersion": "2017-05-01-preview", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}/blobServices/{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), 'default')]", + "name": "[replace(parameters('namingConvention').storageAccountDiagnosticSetting, format('{0}-{1}', parameters('serviceToken'), parameters('resourceAbbreviations').storageAccounts), format('blob-{0}-scale', parameters('resourceAbbreviations').storageAccounts))]", "properties": { "logs": [ { - "categoryGroup": "allLogs", + "category": "StorageWrite", + "enabled": true + } + ], + "metrics": [ + { + "category": "Transaction", "enabled": true } ], "workspaceId": "[parameters('logAnalyticsWorkspaceResourceId')]" }, "dependsOn": [ - "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" + "[resourceId('Microsoft.Storage/storageAccounts/blobServices', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), 'default')]" ] - } - ], - "outputs": { - "name": { - "type": "string", - "value": "[parameters('hostPoolName')]" - }, - "resourceId": { - "type": "string", - "value": "[resourceId('Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName'))]" - } - } - } - } - }, - { - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-vdag-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupControlPlane')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "deploymentNameSuffix": { - "value": "[parameters('deploymentNameSuffix')]" - }, - "deploymentUserAssignedIdentityClientId": { - "value": "[parameters('deploymentUserAssignedIdentityClientId')]" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "value": "[parameters('deploymentUserAssignedIdentityPrincipalId')]" - }, - "desktopApplicationGroupName": { - "value": "[replace(parameters('namingConvention').applicationGroup, parameters('serviceToken'), 'desktop')]" - }, - "hostPoolResourceId": { - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupControlPlane')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" - }, - "locationControlPlane": { - "value": "[parameters('locationControlPlane')]" - }, - "locationVirtualMachines": { - "value": "[parameters('locationVirtualMachines')]" - }, - "mlzTags": { - "value": "[parameters('mlzTags')]" - }, - "resourceGroupManagement": { - "value": "[parameters('resourceGroupManagement')]" - }, - "roleDefinitions": { - "value": "[parameters('roleDefinitions')]" - }, - "securityPrincipalObjectIds": { - "value": "[parameters('securityPrincipalObjectIds')]" - }, - "desktopFriendlyName": { - "value": "[parameters('desktopFriendlyName')]" - }, - "tags": { - "value": "[parameters('tags')]" - }, - "virtualMachineName": { - "value": "[parameters('managementVirtualMachineName')]" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "10581081897017236090" - } - }, - "parameters": { - "deploymentNameSuffix": { - "type": "string" - }, - "deploymentUserAssignedIdentityClientId": { - "type": "string" - }, - "deploymentUserAssignedIdentityPrincipalId": { - "type": "string" - }, - "desktopApplicationGroupName": { - "type": "string" - }, - "desktopFriendlyName": { - "type": "string" - }, - "hostPoolResourceId": { - "type": "string" - }, - "locationControlPlane": { - "type": "string" - }, - "locationVirtualMachines": { - "type": "string" - }, - "mlzTags": { - "type": "object" - }, - "resourceGroupManagement": { - "type": "string" }, - "roleDefinitions": { - "type": "object" + { + "condition": "[parameters('enableApplicationInsights')]", + "type": "Microsoft.Insights/components", + "apiVersion": "2020-02-02", + "name": "[replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service'))]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Insights/components'), createObject()), parameters('mlzTags'))]", + "properties": { + "Application_Type": "web", + "publicNetworkAccessForIngestion": "Disabled", + "publicNetworkAccessForQuery": "Disabled" + }, + "kind": "web" }, - "securityPrincipalObjectIds": { - "type": "array" + { + "type": "Microsoft.Web/serverfarms", + "apiVersion": "2023-01-01", + "name": "[replace(parameters('namingConvention').appServicePlan, parameters('serviceToken'), variables('service'))]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Web/serverfarms'), createObject()), parameters('mlzTags'))]", + "sku": { + "name": "P1v3", + "tier": "PremiumV3", + "size": "P1v3", + "family": "Pv3", + "capacity": 1 + }, + "kind": "functionapp" }, - "tags": { - "type": "object" + { + "type": "Microsoft.Web/sites", + "apiVersion": "2023-01-01", + "name": "[uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Web/sites'), createObject()), parameters('mlzTags'))]", + "kind": "functionapp", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "clientAffinityEnabled": false, + "httpsOnly": true, + "publicNetworkAccess": "Disabled", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', replace(parameters('namingConvention').appServicePlan, parameters('serviceToken'), variables('service')))]", + "siteConfig": { + "alwaysOn": true, + "appSettings": "[union(createArray(createObject('name', 'AzureWebJobsStorage__blobServiceUri', 'value', format('https://{0}.blob.{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), environment().suffixes.storage)), createObject('name', 'AzureWebJobsStorage__credential', 'value', 'managedidentity'), createObject('name', 'AzureWebJobsStorage__queueServiceUri', 'value', format('https://{0}.queue.{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), environment().suffixes.storage)), createObject('name', 'AzureWebJobsStorage__tableServiceUri', 'value', format('https://{0}.table.{1}', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id), environment().suffixes.storage)), createObject('name', 'FUNCTIONS_EXTENSION_VERSION', 'value', '~4'), createObject('name', 'FUNCTIONS_WORKER_RUNTIME', 'value', 'powershell'), createObject('name', 'WEBSITE_LOAD_USER_PROFILE', 'value', '1'), createObject('name', 'FileShareName', 'value', 'profile-containers'), createObject('name', 'ResourceGroupName', 'value', parameters('resourceGroupProfiles')), createObject('name', 'ResourceManagerUrl', 'value', if(endsWith(environment().resourceManager, '/'), environment().resourceManager, format('{0}/', environment().resourceManager))), createObject('name', 'StorageSuffix', 'value', environment().suffixes.storage), createObject('name', 'SubscriptionId', 'value', subscription().subscriptionId)), if(parameters('enableApplicationInsights'), createArray(createObject('name', 'APPLICATIONINSIGHTS_CONNECTION_STRING', 'value', reference(resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service'))), '2020-02-02').ConnectionString)), createArray()))]", + "cors": { + "allowedOrigins": [ + "[format('{0}', environment().portal)]", + "[format('https://functions-next.{0}', variables('cloudSuffix'))]", + "[format('https://functions-staging.{0}', variables('cloudSuffix'))]", + "[format('https://functions.{0}', variables('cloudSuffix'))]" + ] + }, + "ftpsState": "Disabled", + "netFrameworkVersion": "v6.0", + "powerShellVersion": "7.4", + "publicNetworkAccess": "Disabled", + "use32BitWorkerProcess": false + }, + "virtualNetworkSubnetId": "[parameters('delegatedSubnetResourceId')]", + "vnetContentShareEnabled": false, + "vnetRouteAllEnabled": true + }, + "dependsOn": [ + "[resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service')))]", + "[resourceId('Microsoft.Web/serverfarms', replace(parameters('namingConvention').appServicePlan, parameters('serviceToken'), variables('service')))]", + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" + ] }, - "virtualMachineName": { - "type": "string" - } - }, - "variables": { - "$fxv#0": "Param(\r\n [string]$ApplicationGroupName,\r\n [string]$FriendlyName,\r\n [string]$ResourceGroupName,\r\n [string]$ResourceManagerUri,\r\n [string]$SubscriptionId,\r\n [string]$UserAssignedIdentityClientId\r\n)\r\n\r\n$ErrorActionPreference = 'Stop'\r\n$WarningPreference = 'SilentlyContinue'\r\n\r\n# Wait for role assignment propagation\r\nStart-Sleep -Seconds 30\r\n\r\n# Fix the resource manager URI since only AzureCloud contains a trailing slash\r\n$ResourceManagerUriFixed = if ($ResourceManagerUri[-1] -eq '/') {$ResourceManagerUri} else {$ResourceManagerUri + '/'}\r\n\r\n# Get an access token for Azure resources\r\n$AzureManagementAccessToken = (Invoke-RestMethod `\r\n -Headers @{Metadata=\"true\"} `\r\n -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token\r\n\r\n# Set header for Azure Management API\r\n$AzureManagementHeader = @{\r\n 'Content-Type'='application/json'\r\n 'Authorization'='Bearer ' + $AzureManagementAccessToken\r\n}\r\n\r\n# Update the friendly name on the session desktop\r\nInvoke-RestMethod `\r\n -Body (@{properties = @{friendlyName = $FriendlyName.Replace('\"', '')}} | ConvertTo-Json) `\r\n -Headers $AzureManagementHeader `\r\n -Method 'PATCH' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/applicationGroups/' + $ApplicationGroupName + '/desktops/SessionDesktop?api-version=2022-02-10-preview') | Out-Null" - }, - "resources": [ { - "type": "Microsoft.DesktopVirtualization/applicationGroups", - "apiVersion": "2024-04-03", - "name": "[parameters('desktopApplicationGroupName')]", - "location": "[parameters('locationControlPlane')]", - "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), if(contains(parameters('tags'), 'Microsoft.DesktopVirtualization/applicationGroups'), parameters('tags')['Microsoft.DesktopVirtualization/applicationGroups'], createObject()), parameters('mlzTags'))]", + "type": "Microsoft.Network/privateEndpoints", + "apiVersion": "2023-04-01", + "name": "[replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", "properties": { - "hostPoolArmPath": "[parameters('hostPoolResourceId')]", - "applicationGroupType": "Desktop" - } + "customNetworkInterfaceName": "[replace(parameters('namingConvention').functionAppNetworkInterface, parameters('serviceToken'), variables('service'))]", + "privateLinkServiceConnections": [ + { + "name": "[replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service'))]", + "properties": { + "privateLinkServiceId": "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]", + "groupIds": [ + "sites" + ] + } + } + ], + "subnet": { + "id": "[parameters('subnetResourceId')]" + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]" + ] }, { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.DesktopVirtualization/applicationGroups/{0}', parameters('desktopApplicationGroupName'))]", - "name": "[guid(parameters('deploymentUserAssignedIdentityPrincipalId'), '86240b0e-9422-4c43-887b-b61143f32ba8', resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName')))]", + "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups", + "apiVersion": "2021-08-01", + "name": "[format('{0}/{1}', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')), 'default')]", "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', '86240b0e-9422-4c43-887b-b61143f32ba8')]", - "principalId": "[parameters('deploymentUserAssignedIdentityPrincipalId')]", - "principalType": "ServicePrincipal" + "privateDnsZoneConfigs": [ + { + "name": "ipconfig1", + "properties": { + "privateDnsZoneId": "[format('{0}{1}', parameters('privateDnsZoneResourceIdPrefix'), filter(parameters('privateDnsZones'), lambda('name', contains(lambdaVariables('name'), variables('functionAppKeyword'))))[0])]" + } + } + ] }, "dependsOn": [ - "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]" + "[resourceId('Microsoft.Network/privateEndpoints', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')))]" ] }, { - "copy": { - "name": "roleAssignment_Users", - "count": "[length(range(0, length(parameters('securityPrincipalObjectIds'))))]" - }, - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2022-04-01", - "scope": "[format('Microsoft.DesktopVirtualization/applicationGroups/{0}', parameters('desktopApplicationGroupName'))]", - "name": "[guid(parameters('securityPrincipalObjectIds')[range(0, length(parameters('securityPrincipalObjectIds')))[copyIndex()]], parameters('roleDefinitions').DesktopVirtualizationUser, parameters('desktopApplicationGroupName'))]", + "type": "Microsoft.Web/sites/functions", + "apiVersion": "2020-12-01", + "name": "[format('{0}/{1}', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id), 'auto-increase-file-share-quota')]", "properties": { - "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitions').DesktopVirtualizationUser)]", - "principalId": "[parameters('securityPrincipalObjectIds')[range(0, length(parameters('securityPrincipalObjectIds')))[copyIndex()]]]" + "config": { + "disabled": false, + "bindings": [ + { + "name": "Timer", + "type": "timerTrigger", + "direction": "in", + "schedule": "0 */15 * * * *" + } + ] + }, + "files": { + "requirements.psd1": "[variables('$fxv#0')]", + "run.ps1": "[variables('$fxv#1')]", + "../profile.ps1": "[variables('$fxv#2')]" + } }, "dependsOn": [ - "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]" + "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]" ] }, { - "condition": "[not(empty(parameters('desktopFriendlyName')))]", + "condition": "[parameters('enableApplicationInsights')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-vdapp-friendly-name-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", + "name": "[format('deploy-private-link-scope-appi-{0}', parameters('deploymentNameSuffix'))]", + "subscriptionId": "[split(parameters('privateLinkScopeResourceId'), '/')[2]]", + "resourceGroup": "[split(parameters('privateLinkScopeResourceId'), '/')[4]]", "properties": { "expressionEvaluationOptions": { "scope": "inner" }, "mode": "Incremental", "parameters": { - "location": { - "value": "[parameters('locationVirtualMachines')]" + "applicationInsightsResourceId": { + "value": "[resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service')))]" }, - "name": { - "value": "Update-AvdDesktop" + "privateLinkScopeResourceId": { + "value": "[parameters('privateLinkScopeResourceId')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "6666075809401495349" + } }, "parameters": { - "value": [ - { - "name": "ApplicationGroupName", - "value": "[parameters('desktopApplicationGroupName')]" - }, - { - "name": "FriendlyName", - "value": "[parameters('desktopFriendlyName')]" - }, - { - "name": "ResourceGroupName", - "value": "[resourceGroup().name]" - }, - { - "name": "ResourceManagerUri", - "value": "[environment().resourceManager]" - }, - { - "name": "SubscriptionId", - "value": "[subscription().subscriptionId]" - }, - { - "name": "UserAssignedIdentityClientId", - "value": "[parameters('deploymentUserAssignedIdentityClientId')]" + "applicationInsightsResourceId": { + "type": "string", + "defaultValue": "" + }, + "dataCollectionEndpointResourceId": { + "type": "string", + "defaultValue": "" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "defaultValue": "" + }, + "privateLinkScopeResourceId": { + "type": "string" + } + }, + "resources": [ + { + "condition": "[not(empty(parameters('applicationInsightsResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('applicationInsightsResourceId')), 'applicationInsights', split(parameters('applicationInsightsResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('applicationInsightsResourceId')]" } - ] + }, + { + "condition": "[not(empty(parameters('dataCollectionEndpointResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('dataCollectionEndpointResourceId')), 'dataCollectionEndpoint', split(parameters('dataCollectionEndpointResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('dataCollectionEndpointResourceId')]" + } + }, + { + "condition": "[not(empty(parameters('logAnalyticsWorkspaceResourceId')))]", + "type": "Microsoft.Insights/privateLinkScopes/scopedResources", + "apiVersion": "2021-09-01", + "name": "[format('{0}/{1}', split(parameters('privateLinkScopeResourceId'), '/')[8], if(empty(parameters('logAnalyticsWorkspaceResourceId')), 'logAnalyticsWorkspace', split(parameters('logAnalyticsWorkspaceResourceId'), '/')[8]))]", + "properties": { + "linkedResourceId": "[parameters('logAnalyticsWorkspaceResourceId')]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Insights/components', replace(parameters('namingConvention').applicationInsights, parameters('serviceToken'), variables('service')))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('set-role-assignment-storage-{0}', parameters('deploymentNameSuffix'))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "principalId": { + "value": "[reference(resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)), '2023-01-01', 'full').identity.principalId]" }, - "script": { - "value": "[variables('$fxv#0')]" + "principalType": { + "value": "ServicePrincipal" }, - "tags": { - "value": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), if(contains(parameters('tags'), 'Microsoft.Compute/virtualMachines'), parameters('tags')['Microsoft.Compute/virtualMachines'], createObject()), parameters('mlzTags'))]" + "roleDefinitionId": { + "value": "b7e6dc6d-f1e8-4753-8033-0f276bb0955b" }, - "virtualMachineName": { - "value": "[parameters('virtualMachineName')]" + "storageAccountName": { + "value": "[uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id)]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "9123948093985510582" + } + }, + "parameters": { + "principalId": { + "type": "string" + }, + "principalType": { + "type": "string" + }, + "roleDefinitionId": { + "type": "string" + }, + "storageAccountName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "scope": "[format('Microsoft.Storage/storageAccounts/{0}', parameters('storageAccountName'))]", + "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", + "principalId": "[parameters('principalId')]", + "principalType": "[parameters('principalType')]" + } + } + ] + } + }, + "dependsOn": [ + "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]", + "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), variables('service')), resourceGroup().id))]" + ] + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('deploy-scm-a-record-{0}', parameters('deploymentNameSuffix'))]", + "subscriptionId": "[split(variables('functionAppScmPrivateDnsZoneResourceId'), '/')[2]]", + "resourceGroup": "[split(variables('functionAppScmPrivateDnsZoneResourceId'), '/')[4]]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "functionAppName": { + "value": "[uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)]" + }, + "ipv4Address": { + "value": "[filter(reference(resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')), 'default'), '2021-08-01').privateDnsZoneConfigs[0].properties.recordSets, lambda('record', equals(lambdaVariables('record').recordSetName, uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))))[0].ipAddresses[0]]" + }, + "privateDnsZoneName": { + "value": "[split(variables('functionAppScmPrivateDnsZoneResourceId'), '/')[8]]" } }, "template": { @@ -9894,97 +8863,137 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5317974790875443937" + "version": "0.31.92.45157", + "templateHash": "2293260329720441287" } }, "parameters": { - "asyncExecution": { - "type": "bool", - "defaultValue": false - }, - "location": { - "type": "string" - }, - "name": { + "functionAppName": { "type": "string" }, - "parameters": { - "type": "array", - "defaultValue": [] - }, - "script": { + "ipv4Address": { "type": "string" }, - "tags": { - "type": "object" - }, - "treatFailureAsDeploymentFailure": { - "type": "bool", - "defaultValue": true - }, - "virtualMachineName": { + "privateDnsZoneName": { "type": "string" } }, "resources": [ { - "type": "Microsoft.Compute/virtualMachines/runCommands", - "apiVersion": "2023-09-01", - "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", - "location": "[parameters('location')]", - "tags": "[parameters('tags')]", + "type": "Microsoft.Network/privateDnsZones/A", + "apiVersion": "2020-06-01", + "name": "[format('{0}/{1}', parameters('privateDnsZoneName'), parameters('functionAppName'))]", "properties": { - "asyncExecution": "[parameters('asyncExecution')]", - "parameters": "[parameters('parameters')]", - "source": { - "script": "[parameters('script')]" - }, - "treatFailureAsDeploymentFailure": "[parameters('treatFailureAsDeploymentFailure')]" + "aRecords": [ + { + "ipv4Address": "[parameters('ipv4Address')]" + } + ], + "ttl": 3600 } } ] } }, "dependsOn": [ - "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]", - "[extensionResourceId(resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName')), 'Microsoft.Authorization/roleAssignments', guid(parameters('deploymentUserAssignedIdentityPrincipalId'), '86240b0e-9422-4c43-887b-b61143f32ba8', resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))))]" + "[resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id))]", + "[resourceId('Microsoft.Network/privateEndpoints/privateDnsZoneGroups', replace(parameters('namingConvention').functionAppPrivateEndpoint, parameters('serviceToken'), variables('service')), 'default')]" ] } ], "outputs": { - "resourceId": { + "functionAppName": { "type": "string", - "value": "[resourceId('Microsoft.DesktopVirtualization/applicationGroups', parameters('desktopApplicationGroupName'))]" + "value": "[uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)]" + }, + "functionAppPrincipalId": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Web/sites', uniqueString(replace(parameters('namingConvention').functionApp, parameters('serviceToken'), variables('service')), resourceGroup().id)), '2023-01-01', 'full').identity.principalId]" } } } }, "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupControlPlane')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]" + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix')))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" ] } ], "outputs": { "applicationGroupResourceId": { "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupControlPlane')), 'Microsoft.Resources/deployments', format('deploy-vdag-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdag-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "dataCollectionRuleResourceId": { + "type": "string", + "value": "[if(parameters('enableAvdInsights'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.dataCollectionRuleResourceId.value, '')]" + }, + "deploymentUserAssignedIdentityClientId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.clientId.value]" + }, + "deploymentUserAssignedIdentityPrincipalId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.principalId.value]" + }, + "deploymentUserAssignedIdentityResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-id-deployment-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "diskAccessPolicyDefinitionId": { + "type": "string", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-policy-disks-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.policyDefinitionId.value]" + }, + "diskAccessPolicyDisplayName": { + "type": "string", + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-policy-disks-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.policyDisplayName.value]" + }, + "diskAccessResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-disk-access-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "functionAppPrincipalId": { + "type": "string", + "value": "[if(equals(parameters('fslogixStorageService'), 'AzureFiles Premium'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-function-app-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.functionAppPrincipalId.value, '')]" }, "hostPoolName": { "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupControlPlane')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" }, "hostPoolResourceId": { "type": "string", - "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupControlPlane')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-vdpool-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" + }, + "logAnalyticsWorkspaceName": { + "type": "string", + "value": "[if(or(parameters('enableApplicationInsights'), parameters('enableAvdInsights')), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceName.value, '')]" + }, + "logAnalyticsWorkspaceResourceId": { + "type": "string", + "value": "[if(or(parameters('enableApplicationInsights'), parameters('enableAvdInsights')), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-monitoring-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.logAnalyticsWorkspaceResourceId.value, '')]" + }, + "recoveryServicesVaultName": { + "type": "string", + "value": "[if(parameters('recoveryServices'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-rsv-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value, '')]" + }, + "resourceGroupName": { + "type": "string", + "value": "[parameters('resourceGroupName')]" + }, + "virtualMachineName": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + }, + "virtualMachineResourceId": { + "type": "string", + "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-mgmt-vm-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceId.value]" } } } }, "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix')))]", - "rgs", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix')))]" ] }, @@ -10001,7 +9010,7 @@ "mode": "Incremental", "parameters": { "applicationGroupResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.applicationGroupResourceId.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.applicationGroupResourceId.value]" }, "avdPrivateDnsZoneResourceId": { "value": "[format('{0}{1}', variables('privateDnsZoneResourceIdPrefix'), filter(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value, lambda('name', startsWith(lambdaVariables('name'), 'privatelink.wvd')))[0])]" @@ -10026,7 +9035,7 @@ "value": "[not(empty(parameters('existingFeedWorkspaceResourceId')))]" }, "hostPoolName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolName.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolName.value]" }, "locationControlPlane": { "value": "[reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location]" @@ -10044,7 +9053,7 @@ "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.mlzTags.value]" }, "resourceGroupManagement": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceGroupName.value]" }, "sharedServicesSubnetResourceId": { "value": "[parameters('sharedServicesSubnetResourceId')]" @@ -10053,35 +9062,35 @@ "value": "[parameters('tags')]" }, "workspaceFeedDiagnoticSettingName": { - "value": "[replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeedDiagnosticSetting, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'feed'), format('-{0}', parameters('stampIndex')), '')]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeedDiagnosticSetting]" }, "workspaceFeedName": { - "value": "[replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeed, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'feed'), format('-{0}', parameters('stampIndex')), '')]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeed]" }, "workspaceFeedNetworkInterfaceName": { - "value": "[replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeedNetworkInterface, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'feed'), format('-{0}', parameters('stampIndex')), '')]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeedNetworkInterface]" }, "workspaceFeedPrivateEndpointName": { - "value": "[replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeedPrivateEndpoint, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'feed'), format('-{0}', parameters('stampIndex')), '')]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeedPrivateEndpoint]" }, "workspaceFeedResourceGroupName": { - "value": "[replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'feedWorkspace'), format('-{0}', parameters('stampIndex')), '')]" + "value": "[replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'feedWorkspace'), format('-{0}', parameters('stampIndex')), '')]" }, - "workspaceFriendlyName": "[if(empty(parameters('workspaceFriendlyName')), createObject('value', replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeed, format('-{0}', reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service), ''), format('-{0}', parameters('stampIndex')), '')), createObject('value', format('{0} ({1})', parameters('workspaceFriendlyName'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location)))]", + "workspaceFriendlyName": "[if(empty(parameters('workspaceFriendlyName')), createObject('value', replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceFeed, format('-{0}', reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service), '')), createObject('value', format('{0} ({1})', parameters('workspaceFriendlyName'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').location)))]", "workspaceGlobalName": { - "value": "[replace(replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceGlobal, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'global'), format('-{0}', parameters('stampIndex')), ''), parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceGlobal, parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" }, "workspaceGlobalNetworkInterfaceName": { - "value": "[replace(replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceGlobalNetworkInterface, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'global'), format('-{0}', parameters('stampIndex')), ''), parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceGlobalNetworkInterface, parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" }, "workspaceGlobalPrivateDnsZoneResourceId": { "value": "[format('{0}{1}', variables('privateDnsZoneResourceIdPrefix'), filter(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.privateDnsZones.value, lambda('name', startsWith(lambdaVariables('name'), 'privatelink-global.wvd')))[0])]" }, "workspaceGlobalPrivateEndpointName": { - "value": "[replace(replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceGlobalPrivateEndpoint, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'global'), format('-{0}', parameters('stampIndex')), ''), parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.workspaceGlobalPrivateEndpoint, parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" }, "workspaceGlobalResourceGroupName": { - "value": "[replace(replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'globalWorkspace'), format('-{0}', parameters('stampIndex')), ''), parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" + "value": "[replace(replace(replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.names.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'globalWorkspace'), format('-{0}', parameters('stampIndex')), ''), parameters('identifier'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', split(parameters('hubVirtualNetworkResourceId'), '/')[2], split(parameters('hubVirtualNetworkResourceId'), '/')[4]), 'Microsoft.Network/virtualNetworks', split(parameters('hubVirtualNetworkResourceId'), '/')[8]), '2023-11-01', 'full').tags.resourcePrefix)]" }, "workspacePublicNetworkAccess": { "value": "[parameters('workspacePublicNetworkAccess')]" @@ -10093,8 +9102,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6641458391732609020" + "version": "0.31.92.45157", + "templateHash": "140763294646618507" } }, "parameters": { @@ -10221,8 +9230,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "17445726037807437290" + "version": "0.31.92.45157", + "templateHash": "9371138343009436350" } }, "parameters": { @@ -10309,8 +9318,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "977555068735579352" + "version": "0.31.92.45157", + "templateHash": "3251230175900717239" } }, "parameters": { @@ -10429,8 +9438,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "17445726037807437290" + "version": "0.31.92.45157", + "templateHash": "9371138343009436350" } }, "parameters": { @@ -10511,8 +9520,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1315528727979495191" + "version": "0.31.92.45157", + "templateHash": "10174155731090308034" } }, "parameters": { @@ -10572,8 +9581,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1315528727979495191" + "version": "0.31.92.45157", + "templateHash": "10174155731090308034" } }, "parameters": { @@ -10686,8 +9695,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "11735323070375319176" + "version": "0.31.92.45157", + "templateHash": "10426142527062787497" } }, "parameters": { @@ -10894,8 +9903,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5317974790875443937" + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" } }, "parameters": { @@ -10959,11 +9968,8 @@ } }, "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-cp-{0}', parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-hub-{0}', parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/deployments', format('get-naming-mgmt-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix')))]" ] }, @@ -10994,6 +10000,9 @@ "deploymentUserAssignedIdentityClientId": { "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.deploymentUserAssignedIdentityClientId.value]" }, + "deploymentUserAssignedIdentityPrincipalId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.deploymentUserAssignedIdentityPrincipalId.value]" + }, "dnsServers": { "value": "[string(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.dnsServers.value)]" }, @@ -11024,8 +10033,11 @@ "fslogixStorageService": { "value": "[parameters('fslogixStorageService')]" }, - "functionAppName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.functionAppName.value]" + "functionAppPrincipalId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.functionAppPrincipalId.value]" + }, + "hostPoolResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolResourceId.value]" }, "keyVaultUri": { "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.keyVaultUri.value]" @@ -11051,15 +10063,14 @@ "recoveryServices": { "value": "[parameters('recoveryServices')]" }, - "resourceGroupControlPlane": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[0], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, "resourceGroupManagement": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceGroupName.value]" + }, + "resourceGroupName": { + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'profiles')]" }, - "resourceGroupStorage": "[if(variables('deployFslogix'), createObject('value', reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[3], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value), createObject('value', ''))]", "securityPrincipalNames": { - "value": "[map(parameters('securityPrincipals'), lambda('item', lambdaVariables('item').name))]" + "value": "[map(parameters('securityPrincipals'), lambda('item', lambdaVariables('item').displayName))]" }, "securityPrincipalObjectIds": { "value": "[map(parameters('securityPrincipals'), lambda('item', lambdaVariables('item').objectId))]" @@ -11101,14 +10112,11 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "17423392577111200184" + "version": "0.31.92.45157", + "templateHash": "14643897230641833486" } }, "parameters": { - "existingSharedActiveDirectoryConnection": { - "type": "bool" - }, "activeDirectorySolution": { "type": "string" }, @@ -11127,6 +10135,9 @@ "deploymentUserAssignedIdentityClientId": { "type": "string" }, + "deploymentUserAssignedIdentityPrincipalId": { + "type": "string" + }, "dnsServers": { "type": "string" }, @@ -11142,19 +10153,25 @@ "encryptionUserAssignedIdentityResourceId": { "type": "string" }, + "existingSharedActiveDirectoryConnection": { + "type": "bool" + }, "fileShares": { "type": "array" }, + "fslogixContainerType": { + "type": "string" + }, "fslogixShareSizeInGB": { "type": "int" }, - "fslogixContainerType": { + "fslogixStorageService": { "type": "string" }, - "fslogixStorageService": { + "functionAppPrincipalId": { "type": "string" }, - "functionAppName": { + "hostPoolResourceId": { "type": "string" }, "keyVaultUri": { @@ -11181,13 +10198,10 @@ "recoveryServices": { "type": "bool" }, - "resourceGroupControlPlane": { - "type": "string" - }, "resourceGroupManagement": { "type": "string" }, - "resourceGroupStorage": { + "resourceGroupName": { "type": "string" }, "securityPrincipalObjectIds": { @@ -11225,17 +10239,144 @@ } }, "variables": { - "hostPoolName": "[parameters('namingConvention').hostPool]", - "tagsNetAppAccount": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), variables('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.NetApp/netAppAccounts'), parameters('tags')['Microsoft.NetApp/netAppAccounts'], createObject()), parameters('mlzTags'))]", - "tagsVirtualMachines": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), variables('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Compute/virtualMachines'), parameters('tags')['Microsoft.Compute/virtualMachines'], createObject()), parameters('mlzTags'))]" + "tagsNetAppAccount": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.NetApp/netAppAccounts'), createObject()), parameters('mlzTags'))]", + "tagsVirtualMachines": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/virtualMachines'), createObject()), parameters('mlzTags'))]" }, "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2023-07-01", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Resources/resourceGroups'), createObject()), parameters('mlzTags'))]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('assign-role-storage-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "principalId": { + "value": "[parameters('deploymentUserAssignedIdentityPrincipalId')]" + }, + "principalType": { + "value": "ServicePrincipal" + }, + "roleDefinitionId": { + "value": "17d1049b-9a84-46fb-8f53-869881c3d3ab" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "10174155731090308034" + } + }, + "parameters": { + "principalId": { + "type": "string" + }, + "principalType": { + "type": "string" + }, + "roleDefinitionId": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", + "principalId": "[parameters('principalId')]", + "principalType": "[parameters('principalType')]" + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, + { + "condition": "[equals(parameters('fslogixStorageService'), 'AzureFiles Premium')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('set-role-assignment-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "principalId": { + "value": "[parameters('functionAppPrincipalId')]" + }, + "principalType": { + "value": "ServicePrincipal" + }, + "roleDefinitionId": { + "value": "17d1049b-9a84-46fb-8f53-869881c3d3ab" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "10174155731090308034" + } + }, + "parameters": { + "principalId": { + "type": "string" + }, + "principalType": { + "type": "string" + }, + "roleDefinitionId": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/roleAssignments", + "apiVersion": "2022-04-01", + "name": "[guid(parameters('principalId'), parameters('roleDefinitionId'), resourceGroup().id)]", + "properties": { + "roleDefinitionId": "[resourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]", + "principalId": "[parameters('principalId')]", + "principalType": "[parameters('principalType')]" + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, { "condition": "[equals(parameters('storageService'), 'AzureNetAppFiles')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('deploy-anf-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupStorage')]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -11312,8 +10453,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "2650625569344244687" + "version": "0.31.92.45157", + "templateHash": "17417543434535800430" } }, "parameters": { @@ -11514,8 +10655,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "4329443301777514730" + "version": "0.31.92.45157", + "templateHash": "849953818393496765" } }, "parameters": { @@ -11586,14 +10727,17 @@ } } } - } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] }, { "condition": "[equals(parameters('storageService'), 'AzureFiles')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('deploy-azure-files-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupStorage')]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -11636,11 +10780,8 @@ "fslogixShareSizeInGB": { "value": "[parameters('fslogixShareSizeInGB')]" }, - "fslogixStorageService": { - "value": "[parameters('fslogixStorageService')]" - }, - "functionAppName": { - "value": "[parameters('functionAppName')]" + "hostPoolResourceId": { + "value": "[parameters('hostPoolResourceId')]" }, "keyVaultUri": { "value": "[parameters('keyVaultUri')]" @@ -11666,9 +10807,6 @@ "resourceGroupManagement": { "value": "[parameters('resourceGroupManagement')]" }, - "resourceGroupStorage": { - "value": "[parameters('resourceGroupStorage')]" - }, "securityPrincipalNames": { "value": "[parameters('securityPrincipalNames')]" }, @@ -11699,14 +10837,8 @@ "tags": { "value": "[parameters('tags')]" }, - "hostPoolName": { - "value": "[variables('hostPoolName')]" - }, "mlzTags": { "value": "[parameters('mlzTags')]" - }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" } }, "template": { @@ -11715,8 +10847,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "10921134071123326707" + "version": "0.31.92.45157", + "templateHash": "2895952650836829415" } }, "parameters": { @@ -11756,13 +10888,7 @@ "fslogixContainerType": { "type": "string" }, - "fslogixStorageService": { - "type": "string" - }, - "functionAppName": { - "type": "string" - }, - "hostPoolName": { + "hostPoolResourceId": { "type": "string" }, "keyVaultUri": { @@ -11789,15 +10915,9 @@ "recoveryServicesVaultName": { "type": "string" }, - "resourceGroupControlPlane": { - "type": "string" - }, "resourceGroupManagement": { "type": "string" }, - "resourceGroupStorage": { - "type": "string" - }, "securityPrincipalObjectIds": { "type": "array" }, @@ -11831,9 +10951,6 @@ }, "variables": { "$fxv#0": "param \r\n(\r\n [String]$ActiveDirectorySolution,\r\n [String]$DomainJoinPassword,\r\n [String]$DomainJoinUserPrincipalName,\r\n [String]$FslogixContainerType,\r\n [String]$Netbios,\r\n [String]$OrganizationalUnitPath,\r\n [string]$ResourceManagerUri,\r\n [String]$SecurityPrincipalNames,\r\n [String]$SmbServerLocation,\r\n [String]$StorageAccountPrefix,\r\n [String]$StorageAccountResourceGroupName,\r\n [Int]$StorageCount,\r\n [Int]$StorageIndex,\r\n [String]$StorageService,\r\n [String]$StorageSuffix,\r\n [String]$SubscriptionId,\r\n [String]$UserAssignedIdentityClientId\r\n)\r\n\r\n$ErrorActionPreference = 'Stop'\r\n$WarningPreference = 'SilentlyContinue'\r\n\r\n##############################################################\r\n# Install Active Directory PowerShell module\r\n##############################################################\r\nif($StorageService -eq 'AzureNetAppFiles' -or ($StorageService -eq 'AzureFiles' -and $ActiveDirectorySolution -eq 'ActiveDirectoryDomainServices'))\r\n{\r\n $RsatInstalled = (Get-WindowsFeature -Name 'RSAT-AD-PowerShell').Installed\r\n if(!$RsatInstalled)\r\n {\r\n Install-WindowsFeature -Name 'RSAT-AD-PowerShell' | Out-Null\r\n }\r\n}\r\n\r\n\r\n##############################################################\r\n# Variables\r\n##############################################################\r\n# Convert Security Principal Names from a JSON array to a PowerShell array\r\n[array]$SecurityPrincipalNames = $SecurityPrincipalNames.Replace('\\','') | ConvertFrom-Json\r\n\r\n# Selects the appropraite share names based on the FslogixContainerType param from the deployment\r\n$Shares = switch($FslogixContainerType)\r\n{\r\n 'CloudCacheProfileContainer' {@('profile-containers')}\r\n 'CloudCacheProfileOfficeContainer' {@('office-containers','profile-containers')}\r\n 'ProfileContainer' {@('profile-containers')}\r\n 'ProfileOfficeContainer' {@('office-containers','profile-containers')}\r\n}\r\n\r\nif($StorageService -eq 'AzureNetAppFiles' -or ($StorageService -eq 'AzureFiles' -and $ActiveDirectorySolution -eq 'ActiveDirectoryDomainServices'))\r\n{\r\n # Create Domain credential\r\n $DomainUsername = $DomainJoinUserPrincipalName\r\n $DomainPassword = ConvertTo-SecureString -String $DomainJoinPassword -AsPlainText -Force\r\n [pscredential]$DomainCredential = New-Object System.Management.Automation.PSCredential ($DomainUsername, $DomainPassword)\r\n\r\n # Get Domain information\r\n $Domain = Get-ADDomain -Credential $DomainCredential -Current 'LocalComputer'\r\n}\r\n\r\nif($StorageService -eq 'AzureFiles')\r\n{\r\n $FilesSuffix = '.file.' + $StorageSuffix\r\n\r\n # Fix the resource manager URI since only AzureCloud contains a trailing slash\r\n $ResourceManagerUriFixed = if ($ResourceManagerUri[-1] -eq '/') { $ResourceManagerUri.Substring(0, $ResourceManagerUri.Length - 1) } else { $ResourceManagerUri }\r\n\r\n # Get an access token for Azure resources\r\n $AzureManagementAccessToken = (Invoke-RestMethod `\r\n -Headers @{Metadata = \"true\" } `\r\n -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token\r\n\r\n # Set header for Azure Management API\r\n $AzureManagementHeader = @{\r\n 'Content-Type' = 'application/json'\r\n 'Authorization' = 'Bearer ' + $AzureManagementAccessToken\r\n }\r\n}\r\n\r\n\r\n##############################################################\r\n# Process Storage Resources\r\n##############################################################\r\nfor($i = 0; $i -lt $StorageCount; $i++)\r\n{\r\n # Determine Principal for assignment\r\n $SecurityPrincipalName = $SecurityPrincipalNames[$i]\r\n $Group = $Netbios + '\\' + $SecurityPrincipalName\r\n\r\n # Get storage resource details\r\n switch($StorageService)\r\n {\r\n 'AzureNetAppFiles' {\r\n $Credential = $DomainCredential\r\n $SmbServerName = (Get-ADComputer -Filter \"Name -like 'anf-$SmbServerLocation*'\" -Credential $DomainCredential).Name\r\n $FileServer = '\\\\' + $SmbServerName + '.' + $Domain.DNSRoot\r\n }\r\n 'AzureFiles' {\r\n $StorageAccountName = $($StorageAccountPrefix + ($i + $StorageIndex).ToString().PadLeft(2,'0')).Substring(0,15)\r\n $FileServer = '\\\\' + $StorageAccountName + $FilesSuffix\r\n\r\n # Get the storage account key\r\n $StorageKey = (Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/listKeys?api-version=2023-05-01')).keys[0].value\r\n\r\n # Create credential for accessing the storage account\r\n $StorageUsername = 'Azure\\' + $StorageAccountName\r\n $StoragePassword = ConvertTo-SecureString -String \"$($StorageKey)\" -AsPlainText -Force\r\n [pscredential]$StorageKeyCredential = New-Object System.Management.Automation.PSCredential ($StorageUsername, $StoragePassword)\r\n $Credential = $StorageKeyCredential\r\n\r\n if($ActiveDirectorySolution -eq 'ActiveDirectoryDomainServices')\r\n {\r\n # Get / create kerberos key for Azure Storage Account\r\n $KerberosKey = ((Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/listKeys?api-version=2023-05-01&$expand=kerb')).keys | Where-Object { $_.Keyname -contains 'kerb1' }).Value\r\n \r\n if (!$KerberosKey) \r\n {\r\n Invoke-RestMethod `\r\n -Body (@{keyName = 'kerb1' } | ConvertTo-Json) `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/regenerateKey?api-version=2023-05-01')\r\n \r\n $Key = ((Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/listKeys?api-version=2023-05-01&$expand=kerb')).keys | Where-Object { $_.Keyname -contains 'kerb1' }).Value\r\n } \r\n else \r\n {\r\n $Key = $KerberosKey\r\n }\r\n\r\n # Creates a password for the Azure Storage Account in AD using the Kerberos key\r\n $ComputerPassword = ConvertTo-SecureString -String $Key.Replace(\"'\",\"\") -AsPlainText -Force\r\n\r\n # Create the SPN value for the Azure Storage Account; attribute for computer object in AD \r\n $SPN = 'cifs/' + $StorageAccountName + $FilesSuffix\r\n\r\n # Create the Description value for the Azure Storage Account; attribute for computer object in AD \r\n $Description = \"Computer account object for Azure storage account $($StorageAccountName).\"\r\n\r\n # Create the AD computer object for the Azure Storage Account\r\n $Computer = Get-ADComputer -Credential $DomainCredential -Filter {Name -eq $StorageAccountName}\r\n if($Computer)\r\n {\r\n Remove-ADComputer -Credential $DomainCredential -Identity $StorageAccountName -Confirm:$false\r\n }\r\n $ComputerObject = New-ADComputer -Credential $DomainCredential -Name $StorageAccountName -Path $OrganizationalUnitPath -ServicePrincipalNames $SPN -AccountPassword $ComputerPassword -Description $Description -PassThru\r\n\r\n $Body = (@{\r\n properties = @{\r\n azureFilesIdentityBasedAuthentication = @{\r\n activeDirectoryProperties = @{\r\n accountType = 'Computer'\r\n azureStorageSid = $ComputerObject.SID.Value\r\n domainGuid = $Domain.ObjectGUID.Guid\r\n domainName = $Domain.DNSRoot\r\n domainSid = $Domain.DomainSID.Value\r\n forestName = $Domain.Forest\r\n netBiosDomainName = $Domain.NetBIOSName\r\n samAccountName = $StorageAccountName\r\n }\r\n directoryServiceOptions = 'AD'\r\n }\r\n }\r\n } | ConvertTo-Json -Depth 6 -Compress)\r\n\r\n Invoke-RestMethod `\r\n -Body $Body `\r\n -Headers $AzureManagementHeader `\r\n -Method 'PATCH' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '?api-version=2023-05-01')\r\n \r\n # Set the Kerberos encryption on the computer object\r\n $DistinguishedName = 'CN=' + $StorageAccountName + ',' + $OrganizationalUnitPath\r\n Set-ADComputer -Credential $DomainCredential -Identity $DistinguishedName -KerberosEncryptionType 'AES256' | Out-Null\r\n \r\n # Reset the Kerberos key on the Storage Account\r\n Invoke-RestMethod `\r\n -Body (@{keyName = 'kerb1' } | ConvertTo-Json) `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/regenerateKey?api-version=2023-05-01')\r\n \r\n $Key = ((Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + '/subscriptions/' + $SubscriptionId + '/resourceGroups/' + $StorageAccountResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/listKeys?api-version=2023-05-01&$expand=kerb')).keys | Where-Object { $_.Keyname -contains 'kerb1' }).Value\r\n \r\n # Update the password on the computer object with the new Kerberos key on the Storage Account\r\n $NewPassword = ConvertTo-SecureString -String $Key -AsPlainText -Force\r\n Set-ADAccountPassword -Credential $DomainCredential -Identity $DistinguishedName -Reset -NewPassword $NewPassword | Out-Null\r\n }\r\n }\r\n }\r\n \r\n foreach($Share in $Shares)\r\n {\r\n # Mount file share\r\n $FileShare = $FileServer + '\\' + $Share\r\n New-PSDrive -Name 'Z' -PSProvider 'FileSystem' -Root $FileShare -Credential $Credential | Out-Null\r\n\r\n # Set recommended NTFS permissions on the file share\r\n $ACL = Get-Acl -Path 'Z:'\r\n $CreatorOwner = New-Object System.Security.Principal.Ntaccount (\"Creator Owner\")\r\n $ACL.PurgeAccessRules($CreatorOwner)\r\n $AuthenticatedUsers = New-Object System.Security.Principal.Ntaccount (\"Authenticated Users\")\r\n $ACL.PurgeAccessRules($AuthenticatedUsers)\r\n $Users = New-Object System.Security.Principal.Ntaccount (\"Users\")\r\n $ACL.PurgeAccessRules($Users)\r\n $DomainUsers = New-Object System.Security.AccessControl.FileSystemAccessRule(\"$Group\",\"Modify\",\"None\",\"None\",\"Allow\")\r\n $ACL.SetAccessRule($DomainUsers)\r\n $CreatorOwner = New-Object System.Security.AccessControl.FileSystemAccessRule(\"Creator Owner\",\"Modify\",\"ContainerInherit,ObjectInherit\",\"InheritOnly\",\"Allow\")\r\n $ACL.AddAccessRule($CreatorOwner)\r\n $ACL | Set-Acl -Path 'Z:' | Out-Null\r\n\r\n # Unmount file share\r\n Remove-PSDrive -Name 'Z' -PSProvider 'FileSystem' -Force | Out-Null\r\n Start-Sleep -Seconds 5 | Out-Null\r\n }\r\n}", - "$fxv#1": "# This file enables modules to be automatically managed by the Functions service.\r\n# See https://aka.ms/functionsmanageddependency for additional information.\r\n#\r\n@{\r\n # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'. \r\n # To use the Az module in your function app, please uncomment the line below.\r\n # 'Az' = '7.*'\r\n}", - "$fxv#2": "param($Timer)\r\n\r\ntry\r\n{\r\n\t[string]$FileShareName = $env:FileShareName\r\n\t[string]$ResourceGroupName = $env:ResourceGroupName\r\n\t[string]$ResourceManagerUrl = $env:ResourceManagerUrl\r\n\t[string]$StorageSuffix = $env:StorageSuffix\r\n\t[string]$SubscriptionId = $env:SubscriptionId\r\n\r\n\t$ErrorActionPreference = 'Stop'\r\n\t$WarningPreference = 'SilentlyContinue'\r\n\r\n\t#region Functions\r\n\tfunction Write-Log \r\n {\r\n\t\t[CmdletBinding()]\r\n\t\tparam (\r\n\t\t\t[Parameter(Mandatory = $false)]\r\n\t\t\t[switch]$Err,\r\n\r\n\t\t\t[Parameter(Mandatory = $true)]\r\n\t\t\t[string]$Message,\r\n\r\n\t\t\t[Parameter(Mandatory = $true)]\r\n\t\t\t[string]$ResourceName,\r\n\r\n\t\t\t[Parameter(Mandatory = $false)]\r\n\t\t\t[switch]$Warn\r\n\t\t)\r\n\r\n\t\t[string]$MessageTimeStamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'\r\n\t\t$Message = \"[$($MyInvocation.ScriptLineNumber)] [$($ResourceName)] $Message\"\r\n\t\t[string]$WriteMessage = \"[$($MessageTimeStamp)] $Message\"\r\n\r\n\t\tif ($Err)\r\n {\r\n\t\t\tWrite-Error $WriteMessage\r\n\t\t\t$Message = \"ERROR: $Message\"\r\n\t\t}\r\n\t\telseif ($Warn)\r\n {\r\n\t\t\tWrite-Warning $WriteMessage\r\n\t\t\t$Message = \"WARN: $Message\"\r\n\t\t}\r\n\t\telse \r\n {\r\n\t\t\tWrite-Output $WriteMessage\r\n\t\t}\r\n\t}\r\n\t#endregion Functions\r\n\r\n\t# Note: https://stackoverflow.com/questions/41674518/powershell-setting-security-protocol-to-tls-1-2\r\n\t[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\r\n\r\n\r\n\t#region Azure Authentication\r\n $AccessToken = $null\r\n try\r\n {\r\n\t\t$TokenAuthURI = $env:IDENTITY_ENDPOINT + '?resource=' + $ResourceManagerUrl + '&api-version=2019-08-01'\r\n\t\t$TokenResponse = Invoke-RestMethod -Method Get -Headers @{\"X-IDENTITY-HEADER\"=\"$env:IDENTITY_HEADER\"} -Uri $TokenAuthURI\r\n\t\t$AccessToken = $TokenResponse.access_token\r\n\t\t$Header = @{\r\n\t\t\t'Content-Type'='application/json'\r\n\t\t\t'Authorization'='Bearer ' + $AccessToken\r\n\t\t}\r\n }\r\n catch\r\n {\r\n throw [System.Exception]::new('Failed to authenticate Azure with application ID, tenant ID, subscription ID', $PSItem.Exception)\r\n }\r\n Write-Log -ResourceName \"$SubscriptionId\" -Message \"Successfully authenticated with Azure using a managed identity\"\r\n\t#endregion Azure Authentication\r\n\r\n\t# Get storage accounts\r\n\t$Uri = $ResourceManagerUrl + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.Storage/storageAccounts?api-version=2023-05-01'\r\n\t$StorageAccountNames = (Invoke-RestMethod -Headers $Header -Method 'GET' -Uri $Uri).value.name\r\n\r\n\tforeach($StorageAccountName in $StorageAccountNames)\r\n\t{\r\n\t\t$ShareUpdateUri = $ResourceManagerUrl + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/fileServices/default/shares/' + $FileShareName + '?api-version=2023-05-01'\r\n\r\n\t\t# Get file share info\r\n\t\t$ShareGetUri = $ResourceManagerUrl + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.Storage/storageAccounts/' + $StorageAccountName + '/fileServices/default/shares/' + $FileShareName + '?api-version=2023-05-01&$expand=stats'\r\n\t\t$PFS = (Invoke-RestMethod -Headers $Header -Method 'GET' -Uri $ShareGetUri).properties\r\n\r\n\t\t# Set variables for provisioned capacity and used capacity\r\n\t\t$ProvisionedCapacity = $PFS.shareQuota\r\n\t\t$UsedCapacity = $PFS.ShareUsageBytes\r\n\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Capacity: $($ProvisionedCapacity)GB\"\r\n\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage: $([math]::Round($UsedCapacity/1GB, 0))GB\"\r\n\r\n\t\t# GB Based Scaling\r\n\t\t# No scaling if no usage\r\n\t\tif($UsedCapacity -eq 0)\r\n\t\t{\r\n\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage is 0GB. No Changes.\"\r\n\t\t}\r\n\t\t# Slow scaling up to 500GB\r\n\t\t# Increases share quota by 100GB if less than 50GB remains on the share\r\n\t\t# This allows time for an AVD Stamp to be rolled out \r\n\t\telseif ($ProvisionedCapacity -lt 500)\r\n\t\t{\r\n\t\t\tif (($ProvisionedCapacity - ($UsedCapacity / ([Math]::Pow(2,30)))) -lt 50) {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage has surpassed the Share Quota remaining threshold of 50GB. Increasing the file share quota by 100GB.\" \r\n\t\t\t\t$Quota = $ProvisionedCapacity + 100\r\n\t\t\t\tInvoke-RestMethod `\r\n\t\t\t\t\t-Body (@{properties = @{shareQuota = $Quota}} | ConvertTo-Json) `\r\n\t\t\t\t\t-Headers $Header `\r\n\t\t\t\t\t-Method 'PATCH' `\r\n\t\t\t\t\t-Uri $ShareUpdateUri | Out-Null\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"New Capacity: $($Quota)GB\"\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage is below Share Quota remaining threshold of 50GB. No Changes.\"\r\n\t\t\t}\r\n\t\t}\r\n\t\t# Aggressive scaling\r\n\t\t# Increases share quota by 500GB if less than 500GB remains on the share\r\n\t\t# This ensures plenty of space is available during mass onboarding\r\n\t\telse \r\n\t\t{\r\n\t\t\tif (($ProvisionedCapacity - ($UsedCapacity / ([Math]::Pow(2,30)))) -lt 500) {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage has surpassed the Share Quota remaining threshold of 500GB. Increasing the file share quota by 500GB.\" \r\n\t\t\t\t$Quota = $ProvisionedCapacity + 500\r\n\t\t\t\tInvoke-RestMethod `\r\n\t\t\t\t\t-Body (@{properties = @{shareQuota = $Quota}} | ConvertTo-Json) `\r\n\t\t\t\t\t-Headers $Header `\r\n\t\t\t\t\t-Method 'PATCH' `\r\n\t\t\t\t\t-Uri $ShareUpdateUri | Out-Null\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"New Capacity: $($Quota)GB\"\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Message \"Share Usage is below Share Quota remaining threshold of 500GB. No Changes.\"\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\ncatch \r\n{\r\n\t$ErrContainer = $PSItem\r\n\t# $ErrContainer = $_\r\n\r\n\t[string]$ErrMsg = $ErrContainer | Format-List -Force | Out-String\r\n\t$ErrMsg += \"Version: $Version`n\"\r\n\r\n\tif (Get-Command 'Write-Log' -ErrorAction:SilentlyContinue)\r\n {\r\n\t\tWrite-Log -ResourceName \"$StorageAccountName/$FileShareName\" -Err -Message $ErrMsg -ErrorAction:Continue\r\n\t}\r\n\telse\r\n {\r\n\t\tWrite-Error $ErrMsg -ErrorAction:Continue\r\n\t}\r\n\r\n\tthrow [System.Exception]::new($ErrMsg, $ErrContainer.Exception)\r\n}", - "$fxv#3": "# Authentication is provided in the script", "roleDefinitionId": "0c867c2a-1d8c-454a-a3db-ab2ea1bdc8bb", "smbMultiChannel": { "multichannel": { @@ -11848,10 +10965,10 @@ }, "storageAccountNamePrefix": "[uniqueString(replace(parameters('namingConvention').storageAccount, parameters('serviceToken'), 'file-fslogix'), resourceGroup().id)]", "storageRedundancy": "[if(equals(parameters('availability'), 'availabilityZones'), '_ZRS', '_LRS')]", - "tagsPrivateEndpoints": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Network/privateEndpoints'), parameters('tags')['Microsoft.Network/privateEndpoints'], createObject()), parameters('mlzTags'))]", - "tagsStorageAccounts": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Storage/storageAccounts'), parameters('tags')['Microsoft.Storage/storageAccounts'], createObject()), parameters('mlzTags'))]", - "tagsRecoveryServicesVault": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.recoveryServices/vaults'), parameters('tags')['Microsoft.recoveryServices/vaults'], createObject()), parameters('mlzTags'))]", - "tagsVirtualMachines": "[union(createObject('cm-resource-parent', format('{0}}}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupControlPlane'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Compute/virtualMachines'), parameters('tags')['Microsoft.Compute/virtualMachines'], createObject()), parameters('mlzTags'))]" + "tagsPrivateEndpoints": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/privateEndpoints'), createObject()), parameters('mlzTags'))]", + "tagsStorageAccounts": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Storage/storageAccounts'), createObject()), parameters('mlzTags'))]", + "tagsRecoveryServicesVault": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.recoveryServices/vaults'), createObject()), parameters('mlzTags'))]", + "tagsVirtualMachines": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/virtualMachines'), createObject()), parameters('mlzTags'))]" }, "resources": [ { @@ -12034,8 +11151,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6140806447963417872" + "version": "0.31.92.45157", + "templateHash": "2560784574355796510" } }, "parameters": { @@ -12131,7 +11248,7 @@ }, { "name": "StorageAccountResourceGroupName", - "value": "[parameters('resourceGroupStorage')]" + "value": "[resourceGroup().name]" }, { "name": "StorageCount", @@ -12175,8 +11292,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "4329443301777514730" + "version": "0.31.92.45157", + "templateHash": "849953818393496765" } }, "parameters": { @@ -12266,7 +11383,7 @@ "value": "[parameters('recoveryServicesVaultName')]" }, "resourceGroupStorage": { - "value": "[parameters('resourceGroupStorage')]" + "value": "[resourceGroup().name]" }, "storageAccountNamePrefix": { "value": "[variables('storageAccountNamePrefix')]" @@ -12287,8 +11404,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "7916275533870259687" + "version": "0.31.92.45157", + "templateHash": "11840486447312746268" } }, "parameters": { @@ -12374,8 +11491,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "8886215231939195200" + "version": "0.31.92.45157", + "templateHash": "13786800560391201998" } }, "parameters": { @@ -12429,86 +11546,6 @@ "dependsOn": [ "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('set-ntfs-permissions-{0}', parameters('deploymentNameSuffix')))]" ] - }, - { - "condition": "[and(equals(parameters('fslogixStorageService'), 'AzureFiles Premium'), greater(parameters('storageCount'), 0))]", - "type": "Microsoft.Resources/deployments", - "apiVersion": "2022-09-01", - "name": "[format('deploy-file-share-scaling-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupManagement')]", - "properties": { - "expressionEvaluationOptions": { - "scope": "inner" - }, - "mode": "Incremental", - "parameters": { - "files": { - "value": { - "requirements.psd1": "[variables('$fxv#1')]", - "run.ps1": "[variables('$fxv#2')]", - "../profile.ps1": "[variables('$fxv#3')]" - } - }, - "functionAppName": { - "value": "[parameters('functionAppName')]" - }, - "functionName": { - "value": "auto-increase-file-share-quota" - }, - "schedule": { - "value": "0 */15 * * * *" - } - }, - "template": { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", - "contentVersion": "1.0.0.0", - "metadata": { - "_generator": { - "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "15160754302365390942" - } - }, - "parameters": { - "files": { - "type": "object" - }, - "functionAppName": { - "type": "string" - }, - "functionName": { - "type": "string" - }, - "schedule": { - "type": "string" - } - }, - "resources": [ - { - "type": "Microsoft.Web/sites/functions", - "apiVersion": "2020-12-01", - "name": "[format('{0}/{1}', parameters('functionAppName'), parameters('functionName'))]", - "properties": { - "config": { - "disabled": false, - "bindings": [ - { - "name": "Timer", - "type": "timerTrigger", - "direction": "in", - "schedule": "[parameters('schedule')]" - } - ] - }, - "files": "[parameters('files')]" - } - } - ] - } - }, - "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-backup-{0}', parameters('deploymentNameSuffix')))]" - ] } ], "outputs": { @@ -12518,25 +11555,26 @@ } } } - } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] } ], "outputs": { "netAppShares": { "type": "array", - "value": "[if(equals(parameters('storageService'), 'AzureNetAppFiles'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupStorage')), 'Microsoft.Resources/deployments', format('deploy-anf-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.fileShares.value, createArray('None'))]" + "value": "[if(equals(parameters('storageService'), 'AzureNetAppFiles'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-anf-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.fileShares.value, createArray('None'))]" }, "storageAccountNamePrefix": { "type": "string", - "value": "[if(equals(parameters('storageService'), 'AzureFiles'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupStorage')), 'Microsoft.Resources/deployments', format('deploy-azure-files-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageAccountNamePrefix.value, '')]" + "value": "[if(equals(parameters('storageService'), 'AzureFiles'), reference(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-azure-files-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.storageAccountNamePrefix.value, '')]" } } } }, "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix')))]", - "rgs", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix')))]" ] }, @@ -12584,6 +11622,15 @@ "deploymentUserAssignedIdentityPrincipalId": { "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.deploymentUserAssignedIdentityPrincipalId.value]" }, + "diskAccessPolicyDefinitionId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskAccessPolicyDefinitionId.value]" + }, + "diskAccessPolicyDisplayName": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskAccessPolicyDisplayName.value]" + }, + "diskAccessResourceId": { + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskAccessResourceId.value]" + }, "diskEncryptionSetResourceId": { "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.diskEncryptionSetResourceId.value]" }, @@ -12621,10 +11668,10 @@ "value": "[parameters('fslogixContainerType')]" }, "hostPoolName": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolName.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolName.value]" }, "hostPoolResourceId": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolResourceId.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.hostPoolResourceId.value]" }, "hostPoolType": { "value": "[parameters('hostPoolType')]" @@ -12666,20 +11713,17 @@ "organizationalUnitPath": { "value": "[parameters('organizationalUnitPath')]" }, + "profile": { + "value": "[parameters('profile')]" + }, "recoveryServicesVaultName": { "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.recoveryServicesVaultName.value]" }, - "resourceGroupControlPlane": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[0], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, - "resourceGroupHosts": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[1], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" - }, "resourceGroupManagement": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceGroupName.value]" }, - "roleDefinitions": { - "value": "[variables('roleDefinitions')]" + "resourceGroupName": { + "value": "[replace(reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.namingConvention.value.resourceGroup, reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.tokens.value.service, 'hosts')]" }, "scalingWeekdaysOffPeakStartTime": { "value": "[parameters('scalingWeekdaysOffPeakStartTime')]" @@ -12743,8 +11787,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1578632995564263199" + "version": "0.31.92.45157", + "templateHash": "8274254996075869850" } }, "parameters": { @@ -12781,6 +11825,15 @@ "deploymentUserAssignedIdentityPrincipalId": { "type": "string" }, + "diskAccessPolicyDefinitionId": { + "type": "string" + }, + "diskAccessPolicyDisplayName": { + "type": "string" + }, + "diskAccessResourceId": { + "type": "string" + }, "diskEncryptionSetResourceId": { "type": "string" }, @@ -12808,6 +11861,9 @@ "enableAvdInsights": { "type": "bool" }, + "enableRecoveryServices": { + "type": "bool" + }, "environmentAbbreviation": { "type": "string" }, @@ -12862,23 +11918,17 @@ "organizationalUnitPath": { "type": "string" }, - "enableRecoveryServices": { - "type": "bool" - }, - "recoveryServicesVaultName": { - "type": "string" - }, - "resourceGroupControlPlane": { + "profile": { "type": "string" }, - "resourceGroupHosts": { + "recoveryServicesVaultName": { "type": "string" }, "resourceGroupManagement": { "type": "string" }, - "roleDefinitions": { - "type": "object" + "resourceGroupName": { + "type": "string" }, "scalingWeekdaysOffPeakStartTime": { "type": "string" @@ -12939,22 +11989,103 @@ } }, "variables": { - "$fxv#0": "Param(\r\n [string]$HostPoolResourceId,\r\n [string]$ResourceGroupName,\r\n [string]$ResourceManagerUri,\r\n [string]$ScalingPlanName,\r\n [string]$SubscriptionId,\r\n [string]$UserAssignedIdentityClientId\r\n)\r\n\r\n$ErrorActionPreference = 'Stop'\r\n$WarningPreference = 'SilentlyContinue'\r\n\r\n# Fix the resource manager URI since only AzureCloud contains a trailing slash\r\n$ResourceManagerUriFixed = if($ResourceManagerUri[-1] -eq '/'){$ResourceManagerUri} else {$ResourceManagerUri + '/'}\r\n\r\n# Get an access token for Azure resources\r\n$AzureManagementAccessToken = (Invoke-RestMethod `\r\n -Headers @{Metadata=\"true\"} `\r\n -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token\r\n\r\n# Set header for Azure Management API\r\n$AzureManagementHeader = @{\r\n 'Content-Type'='application/json'\r\n 'Authorization'='Bearer ' + $AzureManagementAccessToken\r\n}\r\n\r\n# Check if the scaling plan exists: https://learn.microsoft.com/rest/api/desktopvirtualization/scaling-plans/list-by-resource-group\r\n$ScalingPlanExists = (Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'GET' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans?api-version=2024-04-03')).value | Where-Object {$_.name -eq $ScalingPlanName}\r\n\r\n# Disable autoscale for the host pool: https://learn.microsoft.com/rest/api/desktopvirtualization/scaling-plans/update\r\nif ($ScalingPlanExists)\r\n{\r\n Invoke-RestMethod `\r\n -Body (@{properties = @{hostPoolReferences = @(@{hostPoolArmPath = $HostPoolResourceId; scalingPlanEnabled = $false})}} | ConvertTo-Json) `\r\n -Headers $AzureManagementHeader `\r\n -Method 'PATCH' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans/' + $ScalingPlanName + '?api-version=2024-04-03') | Out-Null\r\n}", + "$fxv#0": "Param(\r\n [string]$HostPoolResourceId,\r\n [string]$ResourceGroupName,\r\n [string]$ResourceManagerUri,\r\n [string]$ScalingPlanName,\r\n [string]$SubscriptionId,\r\n [string]$UserAssignedIdentityClientId\r\n)\r\n\r\n$ErrorActionPreference = 'Stop'\r\n$WarningPreference = 'SilentlyContinue'\r\n\r\n# Fix the resource manager URI since only AzureCloud contains a trailing slash\r\n$ResourceManagerUriFixed = if($ResourceManagerUri[-1] -eq '/'){$ResourceManagerUri} else {$ResourceManagerUri + '/'}\r\n\r\n# Get an access token for Azure resources\r\n$AzureManagementAccessToken = (Invoke-RestMethod `\r\n -Headers @{Metadata=\"true\"} `\r\n -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token\r\n\r\n# Set header for Azure Management API\r\n$AzureManagementHeader = @{\r\n 'Content-Type'='application/json'\r\n 'Authorization'='Bearer ' + $AzureManagementAccessToken\r\n}\r\n\r\n# Check if the scaling plan exists: https://learn.microsoft.com/rest/api/desktopvirtualization/scaling-plans/list-by-resource-group\r\n$ScalingPlanExists = (Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'GET' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans?api-version=2023-09-05')).value | Where-Object {$_.name -eq $ScalingPlanName}\r\n\r\n# Disable autoscale for the host pool: https://learn.microsoft.com/rest/api/desktopvirtualization/scaling-plans/update\r\nif ($ScalingPlanExists)\r\n{\r\n Invoke-RestMethod `\r\n -Body (@{properties = @{hostPoolReferences = @(@{hostPoolArmPath = $HostPoolResourceId; scalingPlanEnabled = $false})}} | ConvertTo-Json -Depth 3) `\r\n -Headers $AzureManagementHeader `\r\n -Method 'PATCH' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/resourceGroups/' + $ResourceGroupName + '/providers/Microsoft.DesktopVirtualization/scalingPlans/' + $ScalingPlanName + '?api-version=2023-09-05') | Out-Null\r\n}", + "$fxv#1": "param (\r\n [string]$ImageOffer,\r\n [string]$ImagePublisher,\r\n [string]$ImageSku,\r\n [string]$ResourceManagerUri,\r\n [string]$SubscriptionId,\r\n [string]$UserAssignedIdentityClientId\r\n)\r\n\r\n# Fix the resource manager URI since only AzureCloud contains a trailing slash\r\n$ResourceManagerUriFixed = if($ResourceManagerUri[-1] -eq '/'){$ResourceManagerUri} else {$ResourceManagerUri + '/'}\r\n\r\n# Get an access token for Azure resources\r\n$AzureManagementAccessToken = (Invoke-RestMethod `\r\n -Headers @{Metadata=\"true\"} `\r\n -Uri $('http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' + $ResourceManagerUriFixed + '&client_id=' + $UserAssignedIdentityClientId)).access_token\r\n\r\n# Set header for Azure Management API\r\n$AzureManagementHeader = @{\r\n 'Content-Type'='application/json'\r\n 'Authorization'='Bearer ' + $AzureManagementAccessToken\r\n}\r\n\r\n# Use the access token to get the marketplace agreement\r\n$Terms = Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'GET' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/providers/Microsoft.MarketplaceOrdering/agreements/' + $ImagePublisher + '/offers/' + $ImageOffer + '/plans/' + $ImageSku + '?api-version=2021-01-01')\r\n\r\n# Use the access token to set the marketplace agreement\r\nif($Terms.error)\r\n{\r\n Invoke-RestMethod `\r\n -Headers $AzureManagementHeader `\r\n -Method 'POST' `\r\n -Uri $($ResourceManagerUriFixed + 'subscriptions/' + $SubscriptionId + '/providers/Microsoft.MarketplaceOrdering/agreements/' + $ImagePublisher + '/offers/' + $ImageOffer + '/plans/' + $ImageSku + '/sign?api-version=2021-01-01') | Out-Null\r\n}", "availabilitySetNamePrefix": "[parameters('namingConvention').availabilitySet]", - "tagsAvailabilitySets": "[union(createObject('cm-resource-parent', format('{0}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupManagement'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Compute/availabilitySets'), parameters('tags')['Microsoft.Compute/availabilitySets'], createObject()), parameters('mlzTags'))]", - "tagsNetworkInterfaces": "[union(createObject('cm-resource-parent', format('{0}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupManagement'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Network/networkInterfaces'), parameters('tags')['Microsoft.Network/networkInterfaces'], createObject()), parameters('mlzTags'))]", - "tagsRecoveryServicesVault": "[union(createObject('cm-resource-parent', format('{0}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupManagement'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.recoveryServices/vaults'), parameters('tags')['Microsoft.recoveryServices/vaults'], createObject()), parameters('mlzTags'))]", - "tagsVirtualMachines": "[union(createObject('cm-resource-parent', format('{0}/resourceGroups/{1}/providers/Microsoft.DesktopVirtualization/hostpools/{2}', subscription().id, parameters('resourceGroupManagement'), parameters('hostPoolName'))), if(contains(parameters('tags'), 'Microsoft.Compute/virtualMachines'), parameters('tags')['Microsoft.Compute/virtualMachines'], createObject()), parameters('mlzTags'))]", + "tagsVirtualMachines": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/virtualMachines'), createObject()), parameters('mlzTags'))]", "uniqueToken": "[uniqueString(parameters('identifier'), parameters('environmentAbbreviation'), subscription().subscriptionId)]", "virtualMachineNamePrefix": "[replace(parameters('namingConvention').virtualMachine, parameters('serviceToken'), '')]" }, "resources": [ + { + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2023-07-01", + "name": "[parameters('resourceGroupName')]", + "location": "[parameters('location')]", + "tags": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Resources/resourceGroups'), createObject()), parameters('mlzTags'))]" + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('assign-policy-diskAccess-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "diskAccessResourceId": { + "value": "[parameters('diskAccessResourceId')]" + }, + "location": { + "value": "[parameters('location')]" + }, + "policyDefinitionId": { + "value": "[parameters('diskAccessPolicyDefinitionId')]" + }, + "policyDisplayName": { + "value": "[parameters('diskAccessPolicyDisplayName')]" + }, + "policyName": { + "value": "[parameters('diskAccessPolicyDisplayName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "1275953978872597894" + } + }, + "parameters": { + "diskAccessResourceId": { + "type": "string" + }, + "location": { + "type": "string" + }, + "policyDefinitionId": { + "type": "string" + }, + "policyDisplayName": { + "type": "string" + }, + "policyName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Authorization/policyAssignments", + "apiVersion": "2022-06-01", + "name": "[parameters('policyName')]", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "displayName": "[parameters('policyDisplayName')]", + "policyDefinitionId": "[parameters('policyDefinitionId')]", + "parameters": "[if(not(empty(parameters('diskAccessResourceId'))), createObject('diskAccessId', createObject('value', parameters('diskAccessResourceId'))), createObject())]" + } + } + ] + } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] + }, { "condition": "[and(equals(parameters('hostPoolType'), 'Pooled'), equals(parameters('availability'), 'AvailabilitySets'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-avail-{0}', parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupHosts')]", + "name": "[format('deploy-avSets-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -12974,7 +12105,7 @@ "value": "[parameters('location')]" }, "tagsAvailabilitySets": { - "value": "[variables('tagsAvailabilitySets')]" + "value": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Compute/availabilitySets'), createObject()), parameters('mlzTags'))]" } }, "template": { @@ -12983,8 +12114,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "13909498964093142621" + "version": "0.31.92.45157", + "templateHash": "12575584281240773385" } }, "parameters": { @@ -13025,18 +12156,21 @@ } ] } - } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] }, { "copy": { "name": "roleAssignments", "count": "[length(range(0, length(parameters('securityPrincipalObjectIds'))))]" }, - "condition": "[not(contains(parameters('activeDirectorySolution'), 'DomainServices'))]", + "condition": "[contains(parameters('activeDirectorySolution'), 'EntraId')]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-role-assignments-{0}-{1}', range(0, length(parameters('securityPrincipalObjectIds')))[copyIndex()], parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupHosts')]", + "name": "[format('assign-role-{0}-{1}', range(0, length(parameters('securityPrincipalObjectIds')))[copyIndex()], parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -13050,7 +12184,7 @@ "value": "Group" }, "roleDefinitionId": { - "value": "[parameters('roleDefinitions').VirtualMachineUserLogin]" + "value": "fb879df8-f326-4884-b1cf-06f3ad86be52" } }, "template": { @@ -13059,8 +12193,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "1315528727979495191" + "version": "0.31.92.45157", + "templateHash": "10174155731090308034" } }, "parameters": { @@ -13087,12 +12221,15 @@ } ] } - } + }, + "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]" + ] }, { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-disable-autoscale-{0}', parameters('deploymentNameSuffix'))]", + "name": "[format('deploy-disableAutoscale-{0}', parameters('deploymentNameSuffix'))]", "resourceGroup": "[parameters('resourceGroupManagement')]", "properties": { "expressionEvaluationOptions": { @@ -13150,8 +12287,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5317974790875443937" + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" } }, "parameters": { @@ -13203,6 +12340,124 @@ } } }, + { + "condition": "[equals(parameters('profile'), 'ArcGISPro')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('set-marketplaceTerms-{0}', parameters('deploymentNameSuffix'))]", + "resourceGroup": "[parameters('resourceGroupManagement')]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "name": { + "value": "Set-AzureMarketplaceTerms" + }, + "parameters": { + "value": [ + { + "name": "ImageOffer", + "value": "[parameters('imageOffer')]" + }, + { + "name": "ImagePublisher", + "value": "[parameters('imagePublisher')]" + }, + { + "name": "ImageSku", + "value": "[parameters('imageSku')]" + }, + { + "name": "ResourceManagerUri", + "value": "[environment().resourceManager]" + }, + { + "name": "SubscriptionId", + "value": "[subscription().subscriptionId]" + }, + { + "name": "UserAssignedidentityClientId", + "value": "[parameters('deploymentUserAssignedIdentityClientId')]" + } + ] + }, + "script": { + "value": "[variables('$fxv#1')]" + }, + "tags": { + "value": "[variables('tagsVirtualMachines')]" + }, + "virtualMachineName": { + "value": "[parameters('managementVirtualMachineName')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" + } + }, + "parameters": { + "asyncExecution": { + "type": "bool", + "defaultValue": false + }, + "location": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parameters": { + "type": "array", + "defaultValue": [] + }, + "script": { + "type": "string" + }, + "tags": { + "type": "object" + }, + "treatFailureAsDeploymentFailure": { + "type": "bool", + "defaultValue": true + }, + "virtualMachineName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Compute/virtualMachines/runCommands", + "apiVersion": "2023-09-01", + "name": "[format('{0}/{1}', parameters('virtualMachineName'), parameters('name'))]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "asyncExecution": "[parameters('asyncExecution')]", + "parameters": "[parameters('parameters')]", + "source": { + "script": "[parameters('script')]" + }, + "treatFailureAsDeploymentFailure": "[parameters('treatFailureAsDeploymentFailure')]" + } + } + ] + } + }, + "dependsOn": [ + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-disableAutoscale-{0}', parameters('deploymentNameSuffix')))]" + ] + }, { "copy": { "name": "virtualMachines", @@ -13213,7 +12468,7 @@ "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", "name": "[format('deploy-vms-{0}-{1}', sub(range(1, parameters('sessionHostBatchCount'))[copyIndex()], 1), parameters('deploymentNameSuffix'))]", - "resourceGroup": "[parameters('resourceGroupHosts')]", + "resourceGroup": "[parameters('resourceGroupName')]", "properties": { "expressionEvaluationOptions": { "scope": "inner" @@ -13307,8 +12562,8 @@ "organizationalUnitPath": { "value": "[parameters('organizationalUnitPath')]" }, - "resourceGroupControlPlane": { - "value": "[parameters('resourceGroupControlPlane')]" + "profile": { + "value": "[parameters('profile')]" }, "resourceGroupManagement": { "value": "[parameters('resourceGroupManagement')]" @@ -13337,7 +12592,7 @@ "value": "[parameters('subnetResourceId')]" }, "tagsNetworkInterfaces": { - "value": "[variables('tagsNetworkInterfaces')]" + "value": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.Network/networkInterfaces'), createObject()), parameters('mlzTags'))]" }, "tagsVirtualMachines": { "value": "[variables('tagsVirtualMachines')]" @@ -13364,8 +12619,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "16117911452479927621" + "version": "0.31.92.45157", + "templateHash": "10645307132280074356" } }, "parameters": { @@ -13462,7 +12717,7 @@ "organizationalUnitPath": { "type": "string" }, - "resourceGroupControlPlane": { + "profile": { "type": "string" }, "resourceGroupManagement": { @@ -13603,6 +12858,7 @@ "identity": { "type": "SystemAssigned" }, + "plan": "[if(equals(parameters('profile'), 'ArcGISPro'), createObject('name', parameters('imageSku'), 'publisher', parameters('imagePublisher'), 'product', parameters('imageOffer')), null())]", "zones": "[if(equals(parameters('availability'), 'AvailabilityZones'), createArray(parameters('availabilityZones')[mod(range(0, parameters('sessionHostCount'))[copyIndex()], length(parameters('availabilityZones')))]), null())]", "properties": { "availabilitySet": "[if(equals(parameters('availability'), 'AvailabilitySets'), createObject('id', resourceId('Microsoft.Compute/availabilitySets', format('{0}-{1}', parameters('availabilitySetNamePrefix'), padLeft(div(add(range(0, parameters('sessionHostCount'))[copyIndex()], parameters('sessionHostIndex')), 200), 2, '0')))), null())]", @@ -13802,7 +13058,7 @@ }, "protectedSettings": { "Items": { - "RegistrationInfoToken": "[listRegistrationTokens(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupControlPlane')), 'Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName')), '2023-09-05').value[0].token]" + "RegistrationInfoToken": "[listRegistrationTokens(extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.DesktopVirtualization/hostPools', parameters('hostPoolName')), '2023-09-05').value[0].token]" } } }, @@ -14003,8 +13259,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5317974790875443937" + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" } }, "parameters": { @@ -14090,7 +13346,7 @@ }, { "name": "HostPoolResourceGroupName", - "value": "[parameters('resourceGroupControlPlane')]" + "value": "[parameters('resourceGroupManagement')]" }, { "name": "ResourceManagerUri", @@ -14138,8 +13394,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5317974790875443937" + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" } }, "parameters": { @@ -14198,15 +13454,17 @@ } }, "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupHosts')), 'Microsoft.Resources/deployments', format('deploy-avail-{0}', parameters('deploymentNameSuffix')))]", - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-disable-autoscale-{0}', parameters('deploymentNameSuffix')))]" + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupName')), 'Microsoft.Resources/deployments', format('deploy-avSets-{0}', parameters('deploymentNameSuffix')))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-disableAutoscale-{0}', parameters('deploymentNameSuffix')))]", + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('set-marketplaceTerms-{0}', parameters('deploymentNameSuffix')))]" ] }, { "condition": "[and(parameters('enableRecoveryServices'), equals(parameters('hostPoolType'), 'Personal'))]", "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-recovery-services-{0}', parameters('deploymentNameSuffix'))]", + "name": "[format('deploy-recoveryServices-{0}', parameters('deploymentNameSuffix'))]", "resourceGroup": "[parameters('resourceGroupManagement')]", "properties": { "expressionEvaluationOptions": { @@ -14233,7 +13491,7 @@ "value": "[parameters('recoveryServicesVaultName')]" }, "resourceGroupHosts": { - "value": "[parameters('resourceGroupHosts')]" + "value": "[parameters('resourceGroupName')]" }, "resourceGroupManagement": { "value": "[parameters('resourceGroupManagement')]" @@ -14245,7 +13503,7 @@ "value": "[parameters('sessionHostIndex')]" }, "tagsRecoveryServicesVault": { - "value": "[variables('tagsRecoveryServicesVault')]" + "value": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.recoveryServices/vaults'), createObject()), parameters('mlzTags'))]" }, "virtualMachineNamePrefix": { "value": "[variables('virtualMachineNamePrefix')]" @@ -14257,8 +13515,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "3032901180833561492" + "version": "0.31.92.45157", + "templateHash": "16414429800719346251" } }, "parameters": { @@ -14343,8 +13601,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "15863312965086940829" + "version": "0.31.92.45157", + "templateHash": "2762553882428643570" } }, "parameters": { @@ -14402,13 +13660,14 @@ } }, "dependsOn": [ + "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('resourceGroupName'))]", "virtualMachines" ] }, { "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", - "name": "[format('deploy-scaling-plan-{0}', parameters('deploymentNameSuffix'))]", + "name": "[format('deploy-scalingPlan-{0}', parameters('deploymentNameSuffix'))]", "resourceGroup": "[parameters('resourceGroupManagement')]", "properties": { "expressionEvaluationOptions": { @@ -14441,7 +13700,7 @@ "value": "[parameters('namingConvention').scalingPlan]" }, "tags": { - "value": "[parameters('tags')]" + "value": "[union(createObject('cm-resource-parent', parameters('hostPoolResourceId')), coalesce(tryGet(parameters('tags'), 'Microsoft.DesktopVirtualization/scalingPlans'), createObject()), parameters('mlzTags'))]" }, "timeZone": { "value": "[parameters('timeZone')]" @@ -14465,8 +13724,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "665492750417866100" + "version": "0.31.92.45157", + "templateHash": "12064357872576819259" } }, "parameters": { @@ -14603,7 +13862,7 @@ }, "condition": "[equals(parameters('hostPoolType'), 'Pooled')]", "type": "Microsoft.DesktopVirtualization/scalingPlans/pooledSchedules", - "apiVersion": "2024-04-03", + "apiVersion": "2023-09-05", "name": "[format('{0}/{1}', parameters('scalingPlanName'), if(equals(range(0, length(variables('schedules')))[copyIndex()], 0), 'Weekdays', 'Weekends'))]", "properties": "[variables('schedules')[range(0, length(variables('schedules')))[copyIndex()]]]", "dependsOn": [ @@ -14617,7 +13876,7 @@ }, "condition": "[equals(parameters('hostPoolType'), 'Personal')]", "type": "Microsoft.DesktopVirtualization/scalingPlans/personalSchedules", - "apiVersion": "2024-04-03", + "apiVersion": "2023-09-05", "name": "[format('{0}/{1}', parameters('scalingPlanName'), if(equals(range(0, length(variables('schedules')))[copyIndex()], 0), 'Weekdays', 'Weekends'))]", "properties": "[variables('schedules')[range(0, length(variables('schedules')))[copyIndex()]]]", "dependsOn": [ @@ -14664,7 +13923,7 @@ } }, "dependsOn": [ - "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-recovery-services-{0}', parameters('deploymentNameSuffix')))]", + "[extensionResourceId(format('/subscriptions/{0}/resourceGroups/{1}', subscription().subscriptionId, parameters('resourceGroupManagement')), 'Microsoft.Resources/deployments', format('deploy-recoveryServices-{0}', parameters('deploymentNameSuffix')))]", "virtualMachines" ] } @@ -14672,10 +13931,8 @@ } }, "dependsOn": [ - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-control-plane-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-fslogix-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix')))]", - "rgs", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-tier3-avd-{0}', parameters('deploymentNameSuffix')))]" ] }, @@ -14697,7 +13954,7 @@ "value": "[parameters('locationVirtualMachines')]" }, "resourceGroupManagement": { - "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix'))), '2022-09-01').outputs.name.value]" + "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.resourceGroupName.value]" }, "userAssignedIdentityClientId": { "value": "[reference(subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix'))), '2022-09-01').outputs.deploymentUserAssignedIdentityClientId.value]" @@ -14712,8 +13969,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "6161798997000105603" + "version": "0.31.92.45157", + "templateHash": "297418666680418295" } }, "parameters": { @@ -14796,8 +14053,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.31.34.60546", - "templateHash": "5317974790875443937" + "version": "0.31.92.45157", + "templateHash": "6896852651895359166" } }, "parameters": { @@ -14855,7 +14112,6 @@ "dependsOn": [ "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-fslogix-{0}', parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-management-{0}', parameters('deploymentNameSuffix')))]", - "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-rg-{0}-{1}', variables('resourceGroupServices')[2], parameters('deploymentNameSuffix')))]", "[subscriptionResourceId('Microsoft.Resources/deployments', format('deploy-session-hosts-{0}', parameters('deploymentNameSuffix')))]" ] } diff --git a/src/bicep/add-ons/azure-virtual-desktop/uiDefinition.json b/src/bicep/add-ons/azure-virtual-desktop/uiDefinition.json index cce9c2ef3..7ae63ad60 100644 --- a/src/bicep/add-ons/azure-virtual-desktop/uiDefinition.json +++ b/src/bicep/add-ons/azure-virtual-desktop/uiDefinition.json @@ -314,253 +314,6 @@ } ] }, - { - "name": "controlPlane", - "label": "Control Plane", - "elements": [ - { - "name": "hostPool", - "type": "Microsoft.Common.Section", - "visible": true, - "label": "Host Pool", - "elements": [ - { - "name": "validation", - "type": "Microsoft.Common.CheckBox", - "label": "Validation environment", - "visible": "[not(equals(steps('basics').scenario.profile, 'arcGisPro'))]", - "toolTip": "Choose whether to deploy the host pool as a validation environment. This allows you test preview features for AVD before they are released to production.", - "constraints": { - "required": false - } - }, - { - "name": "hostPoolType", - "type": "Microsoft.Common.DropDown", - "visible": true, - "label": "Host Pool Type", - "defaultValue": "Pooled", - "multiLine": true, - "toolTip": "", - "constraints": { - "required": true, - "allowedValues": [ - { - "label": "Pooled", - "value": "Pooled" - }, - { - "label": "Personal", - "value": "Personal" - } - ] - } - }, - { - "name": "workloadType", - "type": "Microsoft.Common.DropDown", - "label": "Workload Type", - "visible": "[or(equals(steps('basics').scenario.profile, 'arcGisPro'), and(equals(steps('basics').scenario.profile, 'generic'), equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled')))]", - "filter": true, - "defaultValue": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), 'Medium', 'Heavy (2 users per core)')]", - "toolTip": "Select the type of image to deploy on the session hosts.", - "multiLine": true, - "constraints": { - "required": true, - "allowedValues": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), parse('[{\"label\": \"Light\",\"description\": \"Simple 2-D map visualizations, basic analyses, and reporting.\",\"value\": 6},{\"label\": \"Medium\",\"description\": \"Advanced 2-D or 3-D map visualizations, multi-source data analyses leveraging geoprocessing tools, reporting, and editing.\",\"value\": 4},{\"label\": \"Heavy\",\"description\": \"Complex 2-D or 3-D map visualizations including advanced symbology, analyses with visability and line of site, reporting, and editing.\",\"value\": 3}]'), parse('[{\"label\": \"Light (6 users per core)\",\"description\": \"Basic data entry tasks\",\"value\": \"6.0\"},{\"label\": \"Medium (4 users per core)\",\"description\": \"Consultants and market researchers\",\"value\": \"4.0\"},{\"label\": \"Heavy (2 users per core)\",\"description\": \"Software engineers and content creators\",\"value\": \"2.0\"},{\"label\": \"Power (1 user per core)\",\"description\": \"Graphic designers, 3D model makers, and machine learning researchers\",\"value\": \"1.0\"}]'))]" - } - }, - { - "name": "customRdpProperties", - "type": "Microsoft.Common.TextBox", - "visible": true, - "label": "Custom RDP properties", - "defaultValue": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), 'use multimon:i:1;drivestoredirect:s:;encode redirected video capture:i:1;redirected video capture encoding quality:i:2;audiomode:i:0;devicestoredirect:s:;redirectclipboard:i:0;redirectcomports:i:0;redirectlocation:i:1;redirectprinters:i:0;redirectsmartcards:i:1;redirectwebauthn:i:1;usbdevicestoredirect:s:;keyboardhook:i:2;', 'audiocapturemode:i:1;camerastoredirect:s:*;use multimon:i:0;drivestoredirect:s:;encode redirected video capture:i:1;redirected video capture encoding quality:i:1;audiomode:i:0;devicestoredirect:s:;redirectclipboard:i:0;redirectcomports:i:0;redirectlocation:i:1;redirectprinters:i:0;redirectsmartcards:i:1;redirectwebauthn:i:1;usbdevicestoredirect:s:;keyboardhook:i:2;')]", - "toolTip": "Specify the configuration for the RDP properties on the AVD host pool.", - "constraints": { - "required": true - } - }, - { - "name": "publicNetworkAccess", - "type": "Microsoft.Common.DropDown", - "visible": true, - "label": "Public network access", - "defaultValue": "Enabled", - "multiLine": true, - "toolTip": "Enabled: allows the host pool to be accessed from both public and private networks. Disabled: allows the host pool to only be accessed via private endpoints.", - "constraints": { - "required": true, - "allowedValues": [ - { - "label": "Disabled", - "value": "Disabled" - }, - { - "label": "Enabled", - "value": "Enabled" - }, - { - "label": "Enabled For Clients Only", - "value": "EnabledForClientsOnly" - }, - { - "label": "Enabled For Session Hosts Only", - "value": "EnabledForSessionHostsOnly" - } - ] - } - } - ] - }, - { - "name": "workspacesApi", - "type": "Microsoft.Solutions.ArmApiControl", - "request": { - "method": "GET", - "path": "[concat(steps('basics').scope.subscription.id, '/providers/Microsoft.DesktopVirtualization/workspaces?api-version=2022-02-10-preview')]" - } - }, - { - "name": "workspace", - "type": "Microsoft.Common.Section", - "visible": "[empty(first(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location)))))]", - "label": "Workspace", - "elements": [ - { - "name": "publicNetworkAccess", - "type": "Microsoft.Common.DropDown", - "visible": true, - "label": "Public network access (feed)", - "defaultValue": "Enabled", - "multiLine": true, - "toolTip": "Enabled: allows the host pool to be accessed from both public and private networks. Disabled: allows the host pool to only be accessed via private endpoints.", - "constraints": { - "required": true, - "allowedValues": [ - { - "label": "Disabled", - "value": "Disabled" - }, - { - "label": "Enabled", - "value": "Enabled" - } - ] - } - } - ] - }, - { - "name": "assignment", - "type": "Microsoft.Common.Section", - "label": "Assignment", - "visible": true, - "elements": [ - { - "name": "description", - "type": "Microsoft.Common.TextBlock", - "visible": true, - "options": { - "text": "To access Azure Virtual Desktop, your end users will need to be assigned to the Desktop Applicaiton Group and if applicable, be given permissions on the storage service for FSLogix. Select the desired security groups below to give access to this AVD stamp. If deploying FSLogix, storage will be deployed for each group to support sharding. Be sure your groups are sized appropriately for each shard.", - "link": { - "label": "Learn more about FSLogix storage options for sizing your groups.", - "uri": "https://learn.microsoft.com/azure/virtual-desktop/store-fslogix-profile" - } - } - }, - { - "name": "groups", - "type": "Microsoft.Common.EditableGrid", - "ariaLabel": "Input the security groups for access to AVD and if applicable, FSLogix. The object ID is a property on the group and can be found in Entra ID.", - "label": "Security Groups", - "visible": true, - "constraints": { - "width": "Full", - "rows": { - "count": { - "min": 1, - "max": 100 - } - }, - "columns": [ - { - "id": "name", - "header": "Name", - "width": "1fr", - "element": { - "type": "Microsoft.Common.TextBox", - "placeholder": "Security Group Name", - "constraints": { - "required": true, - "validations": [] - } - } - }, - { - "id": "objectId", - "header": "Object ID", - "width": "1fr", - "element": { - "type": "Microsoft.Common.TextBox", - "placeholder": "Security Group Object ID", - "constraints": { - "required": true, - "validations": [] - } - } - } - ] - } - } - ] - }, - { - "name": "friendlyNames", - "type": "Microsoft.Common.Section", - "label": "Friendly Names for AVD Client", - "visible": true, - "elements": [ - { - "name": "custom", - "type": "Microsoft.Common.CheckBox", - "visible": true, - "label": "Custom friendly names?", - "defaultValue": false, - "toolTip": "Choose whether to add custom names to the AVD feed workspace and the desktop for the AVD client." - }, - { - "name": "feedWorkspace", - "type": "Microsoft.Common.TextBox", - "label": "Feed Workspace", - "defaultValue": "", - "placeholder": "Example: Information Technology", - "toolTip": "Input the friendly name for the AVD workspace that will be displayed in the end user's client. This value should apply to all the stamp indexes within the same identifier and would mostly likely represent your business unit or project.", - "visible": "[and(steps('controlPlane').friendlyNames.custom, empty(first(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))))))]", - "constraints": { - "required": false, - "regex": "^.{1,64}$", - "validationMessage": "The value must be between 1 and 64 characters in length." - } - }, - { - "name": "sessionDesktop", - "type": "Microsoft.Common.TextBox", - "label": "Desktop", - "defaultValue": "", - "placeholder": "Example: Help Desk", - "toolTip": "Input the friendly name for the AVD Session Desktop application that will be displayed in the end user's client. This value should represent the workload (eg., Help Desk, Development, or Administration) that will be supported on the host pool.", - "visible": "[steps('controlPlane').friendlyNames.custom]", - "constraints": { - "required": false, - "regex": "^.{1,64}$", - "validationMessage": "The value must be between 1 and 64 characters in length." - } - } - ] - } - ] - }, { "name": "hosts", "label": "Session Hosts", @@ -771,7 +524,7 @@ }, "osPlatform": "Windows", "count": "[steps('hosts').virtualMachines.count]", - "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), and(equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 6)))]" + "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), and(equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 6)))]" }, { "name": "sizeArcGisProSingleMedium", @@ -798,7 +551,7 @@ }, "osPlatform": "Windows", "count": "[steps('hosts').virtualMachines.count]", - "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 4))]" + "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 4))]" }, { "name": "sizeArcGisProSingleHeavy", @@ -823,7 +576,7 @@ }, "osPlatform": "Windows", "count": "[steps('hosts').virtualMachines.count]", - "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 3))]" + "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 3))]" }, { "name": "sizeArcGisProMulti", @@ -846,7 +599,7 @@ }, "osPlatform": "Windows", "count": "[steps('hosts').virtualMachines.count]", - "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled'))]" + "visible": "[and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Pooled'))]" }, { "name": "resourceSkusApi", @@ -1114,6 +867,254 @@ "name": "management", "label": "Management", "elements": [ + { + "name": "hostPool", + "type": "Microsoft.Common.Section", + "visible": true, + "label": "Host Pool", + "elements": [ + { + "name": "validation", + "type": "Microsoft.Common.CheckBox", + "label": "Validation environment", + "visible": "[not(equals(steps('basics').scenario.profile, 'arcGisPro'))]", + "toolTip": "Choose whether to deploy the host pool as a validation environment. This allows you test preview features for AVD before they are released to production.", + "constraints": { + "required": false + } + }, + { + "name": "hostPoolType", + "type": "Microsoft.Common.DropDown", + "visible": true, + "label": "Host Pool Type", + "defaultValue": "Pooled", + "multiLine": true, + "toolTip": "", + "constraints": { + "required": true, + "allowedValues": [ + { + "label": "Pooled", + "value": "Pooled" + }, + { + "label": "Personal", + "value": "Personal" + } + ] + } + }, + { + "name": "workloadType", + "type": "Microsoft.Common.DropDown", + "label": "Workload Type", + "visible": "[or(equals(steps('basics').scenario.profile, 'arcGisPro'), and(equals(steps('basics').scenario.profile, 'generic'), equals(steps('management').hostPool.hostPoolType, 'Pooled')))]", + "filter": true, + "defaultValue": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), 'Medium', 'Heavy (2 users per core)')]", + "toolTip": "Select the type of image to deploy on the session hosts.", + "multiLine": true, + "constraints": { + "required": true, + "allowedValues": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), parse('[{\"label\": \"Light\",\"description\": \"Simple 2-D map visualizations, basic analyses, and reporting.\",\"value\": 6},{\"label\": \"Medium\",\"description\": \"Advanced 2-D or 3-D map visualizations, multi-source data analyses leveraging geoprocessing tools, reporting, and editing.\",\"value\": 4},{\"label\": \"Heavy\",\"description\": \"Complex 2-D or 3-D map visualizations including advanced symbology, analyses with visability and line of site, reporting, and editing.\",\"value\": 3}]'), parse('[{\"label\": \"Light (6 users per core)\",\"description\": \"Basic data entry tasks\",\"value\": \"6.0\"},{\"label\": \"Medium (4 users per core)\",\"description\": \"Consultants and market researchers\",\"value\": \"4.0\"},{\"label\": \"Heavy (2 users per core)\",\"description\": \"Software engineers and content creators\",\"value\": \"2.0\"},{\"label\": \"Power (1 user per core)\",\"description\": \"Graphic designers, 3D model makers, and machine learning researchers\",\"value\": \"1.0\"}]'))]" + } + }, + { + "name": "customRdpProperties", + "type": "Microsoft.Common.TextBox", + "visible": true, + "label": "Custom RDP properties", + "defaultValue": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), 'use multimon:i:1;drivestoredirect:s:;encode redirected video capture:i:1;redirected video capture encoding quality:i:2;audiomode:i:0;devicestoredirect:s:;redirectclipboard:i:0;redirectcomports:i:0;redirectlocation:i:1;redirectprinters:i:0;redirectsmartcards:i:1;redirectwebauthn:i:1;usbdevicestoredirect:s:;keyboardhook:i:2;', 'audiocapturemode:i:1;camerastoredirect:s:*;use multimon:i:0;drivestoredirect:s:;encode redirected video capture:i:1;redirected video capture encoding quality:i:1;audiomode:i:0;devicestoredirect:s:;redirectclipboard:i:0;redirectcomports:i:0;redirectlocation:i:1;redirectprinters:i:0;redirectsmartcards:i:1;redirectwebauthn:i:1;usbdevicestoredirect:s:;keyboardhook:i:2;')]", + "toolTip": "Specify the configuration for the RDP properties on the AVD host pool.", + "constraints": { + "required": true + } + }, + { + "name": "publicNetworkAccess", + "type": "Microsoft.Common.DropDown", + "visible": true, + "label": "Public network access", + "defaultValue": "Enabled", + "multiLine": true, + "toolTip": "Enabled: allows the host pool to be accessed from both public and private networks. Disabled: allows the host pool to only be accessed via private endpoints.", + "constraints": { + "required": true, + "allowedValues": [ + { + "label": "Disabled", + "value": "Disabled" + }, + { + "label": "Enabled", + "value": "Enabled" + }, + { + "label": "Enabled For Clients Only", + "value": "EnabledForClientsOnly" + }, + { + "label": "Enabled For Session Hosts Only", + "value": "EnabledForSessionHostsOnly" + } + ] + } + } + ] + }, + { + "name": "workspacesApi", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { + "method": "GET", + "path": "[concat(steps('basics').scope.subscription.id, '/providers/Microsoft.DesktopVirtualization/workspaces?api-version=2022-02-10-preview')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.Section", + "visible": "[empty(first(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location)))))]", + "label": "Workspace", + "elements": [ + { + "name": "publicNetworkAccess", + "type": "Microsoft.Common.DropDown", + "visible": true, + "label": "Public network access (feed)", + "defaultValue": "Enabled", + "multiLine": true, + "toolTip": "Enabled: allows the host pool to be accessed from both public and private networks. Disabled: allows the host pool to only be accessed via private endpoints.", + "constraints": { + "required": true, + "allowedValues": [ + { + "label": "Disabled", + "value": "Disabled" + }, + { + "label": "Enabled", + "value": "Enabled" + } + ] + } + } + ] + }, + { + "name": "assignment", + "type": "Microsoft.Common.Section", + "label": "Assignment", + "visible": true, + "elements": [ + { + "name": "description", + "type": "Microsoft.Common.TextBlock", + "visible": true, + "options": { + "text": "To access Azure Virtual Desktop, your end users will need to be assigned to the Desktop Applicaiton Group and if applicable, be given permissions on the storage service for FSLogix. Select the desired security groups below to give access to this AVD stamp. If deploying FSLogix, storage will be deployed for each group to support sharding. Be sure your groups are sized appropriately for each shard.", + "link": { + "label": "Learn more about FSLogix storage options for sizing your groups.", + "uri": "https://learn.microsoft.com/azure/virtual-desktop/store-fslogix-profile" + } + } + }, + { + "name": "groupPickerBlade", + "type": "Microsoft.Solutions.BladeInvokeControl", + "openBladeStatus": "[steps('management').assignment.groupSelector.changing]", + "bladeReference": { + "name": "ObjectPickerBlade", + "extension": "Microsoft_AAD_IAM", + "parameters": { + "queries": 32, + "disablers": 4, + "bladeSubtitle": "Pick the groups to assign", + "additionalQueriesOnSearch": 0, + "advancedQueryOptions": { + "suggestedObjectsOptions": {} + }, + "selectionMaximum": 100, + "selectionMinimum": 1, + "bladeTitle": "Select Groups", + "informationHeader": { + "informationText": "Select the groups that require access to the AVD stamp", + "informationLink": "" + }, + "inviteEnabled": true, + "searchBoxLabel": "Search for a group", + "searchBoxPlaceHolderText": "Enter a string in the group name", + "searchBoxTooltip": "This is the tooltip", + "searchGridNoRowsMessage": "No groups found", + "selectButtonText": "Select Groups", + "selectedGridLabel": "Selected Groups", + "selectedGridNoRowsMessage": "You must select at least one group" + }, + "inFullScreen": false + }, + "transforms": { + "selection": "selectedObjects|[*].{displayName:displayName, objectId:id}" + } + }, + { + "name": "groupSelector", + "type": "Microsoft.Common.Selector", + "label": "Select Groups", + "keyPath": "displayName", + "descriptionKeyPath": "id", + "value": "[steps('management').assignment.groupPickerBlade.transformed.selection]", + "visible": true, + "barColor": "[if(empty(steps('management').assignment.groupPickerBlade), '#FF0000', '#7fba00')]", + "constraints": { + "required": true + }, + "link": "[if(empty(steps('management').assignment.groupPickerBlade), 'Select groups', 'Re-select groups')]" + } + ] + }, + { + "name": "friendlyNames", + "type": "Microsoft.Common.Section", + "label": "Friendly Names for AVD Client", + "visible": true, + "elements": [ + { + "name": "custom", + "type": "Microsoft.Common.CheckBox", + "visible": true, + "label": "Custom friendly names?", + "defaultValue": false, + "toolTip": "Choose whether to add custom names to the AVD feed workspace and the desktop for the AVD client." + }, + { + "name": "feedWorkspace", + "type": "Microsoft.Common.TextBox", + "label": "Feed Workspace", + "defaultValue": "", + "placeholder": "Example: Information Technology", + "toolTip": "Input the friendly name for the AVD workspace that will be displayed in the end user's client. This value should apply to all the stamp indexes within the same identifier and would mostly likely represent your business unit or project.", + "visible": "[and(steps('management').friendlyNames.custom, empty(first(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))))))]", + "constraints": { + "required": false, + "regex": "^.{1,64}$", + "validationMessage": "The value must be between 1 and 64 characters in length." + } + }, + { + "name": "sessionDesktop", + "type": "Microsoft.Common.TextBox", + "label": "Desktop", + "defaultValue": "", + "placeholder": "Example: Help Desk", + "toolTip": "Input the friendly name for the AVD Session Desktop application that will be displayed in the end user's client. This value should represent the workload (eg., Help Desk, Development, or Administration) that will be supported on the host pool.", + "visible": "[steps('management').friendlyNames.custom]", + "constraints": { + "required": false, + "regex": "^.{1,64}$", + "validationMessage": "The value must be between 1 and 64 characters in length." + } + } + ] + }, { "name": "servicePrincipalsApi", "type": "Microsoft.Solutions.GraphApiControl", @@ -1315,7 +1316,7 @@ } }, { - "name": "controlPlaneSubnetAddressCidrRange", + "name": "managementSubnetAddressCidrRange", "label": "Control Plane Subnet CIDR range", "type": "Microsoft.Common.TextBox", "defaultValue": "[concat('10.0.1', string(add(41, mul(2, steps('basics').naming.stampIndex))), '.0/26')]", @@ -1328,19 +1329,19 @@ "message": "Invalid CIDR range. The address prefix must be in the range [24,28]." }, { - "isValid": "[if(greaterOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), 8), equals(last(take(split(first(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), '.'), 1)), last(take(split(first(split(steps('network').vnet.controlPlaneSubnetAddressCidrRange, '/')), '.'), 1))), true)]", + "isValid": "[if(greaterOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), 8), equals(last(take(split(first(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), '.'), 1)), last(take(split(first(split(steps('network').vnet.managementSubnetAddressCidrRange, '/')), '.'), 1))), true)]", "message": "CIDR range not within virtual network CIDR range (first octet)." }, { - "isValid": "[if(greaterOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), 16), equals(last(take(split(first(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), '.'), 2)), last(take(split(first(split(steps('network').vnet.controlPlaneSubnetAddressCidrRange, '/')), '.'), 2))), true)]", + "isValid": "[if(greaterOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), 16), equals(last(take(split(first(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), '.'), 2)), last(take(split(first(split(steps('network').vnet.managementSubnetAddressCidrRange, '/')), '.'), 2))), true)]", "message": "CIDR range not within virtual network CIDR range (second octet)." }, { - "isValid": "[if(greaterOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), 24), equals(last(take(split(first(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), '.'), 3)), last(take(split(first(split(steps('network').vnet.controlPlaneSubnetAddressCidrRange, '/')), '.'), 3))), true)]", + "isValid": "[if(greaterOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), 24), equals(last(take(split(first(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), '.'), 3)), last(take(split(first(split(steps('network').vnet.managementSubnetAddressCidrRange, '/')), '.'), 3))), true)]", "message": "CIDR range not within virtual network CIDR range (third octet)." }, { - "isValid": "[lessOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), last(split(steps('network').vnet.controlPlaneSubnetAddressCidrRange, '/')))]", + "isValid": "[lessOrEquals(last(split(steps('network').vnet.virtualNetworkAddressCidrRange, '/')), last(split(steps('network').vnet.managementSubnetAddressCidrRange, '/')))]", "message": "CIDR range not within virtual network CIDR range (subnet mask)." } ] @@ -1572,6 +1573,8 @@ "Microsoft.Compute/virtualMachines", "Microsoft.DesktopVirtualization/applicationGroups", "Microsoft.DesktopVirtualization/hostPools", + "Microsoft.DesktopVirtualization/scalingPlans", + "Microsoft.DesktopVirtualization/workspaces", "Microsoft.Insights/components", "Microsoft.Insights/dataCollectionEndpoints", "Microsoft.Insights/dataCollectionRules", @@ -1600,34 +1603,34 @@ "parameters": { "activeDirectorySolution": "[if(and(equals(steps('hosts').identity.solution, 'MicrosoftEntraId'), steps('hosts').identity.intune), 'MicrosoftEntraIdIntuneEnrollment', steps('hosts').identity.solution)]", "availability": "[steps('hosts').virtualMachines.availability]", - "availabilityZones": "[first(map(first(map(filter(steps('hosts').virtualMachines.resourceSkusApi.value, (item) => contains(item.name, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric)))))), (item) => item.locationInfo)), (item) => item.zones))]", + "availabilityZones": "[first(map(first(map(filter(steps('hosts').virtualMachines.resourceSkusApi.value, (item) => contains(item.name, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric)))))), (item) => item.locationInfo)), (item) => item.zones))]", "avdObjectId": "[first(map(steps('management').servicePrincipalsApi.value, (item) => item.id))]", "azureNetAppFilesSubnetAddressPrefix": "[steps('network').vnet.azureNetAppFilesSubnetAddressCidrRange]", - "customRdpProperty": "[steps('controlPlane').hostPool.customRdpProperties]", + "customRdpProperty": "[steps('management').hostPool.customRdpProperties]", "deployActivityLogDiagnosticSetting": "[empty(steps('compliance').diagnosticSettingsApi.value)]", "deployDefender": "[and(steps('compliance').defenderForCloud.deployDefender, empty(steps('compliance').defenderForCloud.workspaceSettingsApi.value))]", "deployNetworkWatcher": "[empty(filter(steps('basics').networkWatchersApi.value, (item) => equals(item.location, steps('basics').scope.location.name)))]", "deployPolicy": "[steps('compliance').policySection.deployPolicy]", - "desktopFriendlyName": "[steps('controlPlane').friendlyNames.sessionDesktop]", + "desktopFriendlyName": "[steps('management').friendlyNames.sessionDesktop]", "diskSku": "[if(equals(steps('basics').scenario.profile, 'arcGisPro'), 'Premium_LRS', steps('hosts').virtualMachines.diskSku)]", "domainJoinPassword": "[steps('hosts').domainJoinCredentials.domainPassword]", "domainJoinUserPrincipalName": "[steps('hosts').domainJoinCredentials.domainUserPrincipalName]", "domainName": "[steps('hosts').identity.domainName]", "drainMode": "[steps('management').drainMode.enableDrainMode]", "emailSecurityContact": "[if(and(steps('compliance').defenderForCloud.deployDefender, empty(steps('compliance').defenderForCloud.workspaceSettingsApi.value)), steps('compliance').defenderForCloud.emailSecurityContact, '')]", - "enableAcceleratedNetworking": "[bool(first(map(filter(first(map(filter(steps('hosts').virtualMachines.resourceSkusApi.value, (item) => contains(item.name, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric)))))), (item) => item.capabilities)), (item) => equals(item.name, 'AcceleratedNetworkingEnabled')), (item) => item.value)))]", + "enableAcceleratedNetworking": "[bool(first(map(filter(first(map(filter(steps('hosts').virtualMachines.resourceSkusApi.value, (item) => contains(item.name, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric)))))), (item) => item.capabilities)), (item) => equals(item.name, 'AcceleratedNetworkingEnabled')), (item) => item.value)))]", "enableApplicationInsights": "[steps('management').monitoring.enableApplicationInsights]", "enableAvdInsights": "[steps('management').monitoring.enableAvdInsights]", "enableTelemetry": "[steps('basics').scenario.enablePartnerTelemetry]", "environmentAbbreviation": "[steps('basics').naming.environment]", "existingSharedActiveDirectoryConnection": "[steps('profiles').storage.existingSharedActiveDirectoryConnection]", - "existingFeedWorkspaceResourceId": "[if(empty(steps('controlPlane').workspacesApi.value), '', first(map(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.id)))]", + "existingFeedWorkspaceResourceId": "[if(empty(steps('management').workspacesApi.value), '', first(map(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.id)))]", "fslogixShareSizeInGB": "[if(equals(steps('profiles').profileSolution, 'local'), 100, steps('profiles').storage.fileShareSize)]", "fslogixContainerType": "[steps('profiles').storage.fslogixContainerType]", "fslogixStorageService": "[if(equals(steps('profiles').profileSolution, 'local'), 'None', steps('profiles').storage.service)]", "functionAppSubnetAddressPrefix": "[steps('network').vnet.functionAppSubnetAddressCidrRange]", - "hostPoolPublicNetworkAccess": "[steps('controlPlane').hostPool.publicNetworkAccess]", - "hostPoolType": "[steps('controlPlane').hostPool.hostPoolType]", + "hostPoolPublicNetworkAccess": "[steps('management').hostPool.publicNetworkAccess]", + "hostPoolType": "[steps('management').hostPool.hostPoolType]", "hubAzureFirewallResourceId": "[steps('basics').hub.azureFirewall]", "hubVirtualNetworkResourceId": "[steps('basics').hub.virtualNetwork]", "identifier": "[steps('basics').naming.identifier]", @@ -1648,24 +1651,24 @@ "scalingWeekdaysPeakStartTime": "[steps('management').scalingPlan.weekdaysPeakStartTime]", "scalingWeekendsOffPeakStartTime": "[steps('management').scalingPlan.weekendsOffPeakStartTime]", "scalingWeekendsPeakStartTime": "[steps('management').scalingPlan.weekendsPeakStartTime]", - "securityPrincipals": "[steps('controlPlane').assignment.groups]", + "securityPrincipals": "[steps('management').assignment.groupPickerBlade.transformed.selection]", "sessionHostCount": "[steps('hosts').virtualMachines.count]", "sessionHostIndex": 0, "sharedServicesSubnetResourceId": "[first(map(steps('basics').sharedServicesSubnetsApi.value, (item) => item.id))]", "stampIndex": "[steps('basics').naming.stampIndex]", - "storageCount": "[if(equals(steps('profiles').profileSolution, 'local'), 0, length(steps('controlPlane').assignment.groups))]", + "storageCount": "[if(equals(steps('profiles').profileSolution, 'local'), 0, length(steps('management').assignment.groupPickerBlade.transformed.selection))]", "storageIndex": 0, - "subnetAddressPrefixes": "[parse(concat('[\"', steps('network').vnet.sessionHostsSubnetAddressCidrRange, '\",\"', steps('network').vnet.controlPlaneSubnetAddressCidrRange, '\"]'))]", + "subnetAddressPrefixes": "[parse(concat('[\"', steps('network').vnet.sessionHostsSubnetAddressCidrRange, '\",\"', steps('network').vnet.managementSubnetAddressCidrRange, '\"]'))]", "tags": "[steps('tags').tags]", - "usersPerCore": "[if(equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled'), steps('controlPlane').hostPool.workloadType, 1)]", - "validationEnvironment": "[steps('controlPlane').hostPool.validation]", + "usersPerCore": "[if(equals(steps('management').hostPool.hostPoolType, 'Pooled'), steps('management').hostPool.workloadType, 1)]", + "validationEnvironment": "[steps('management').hostPool.validation]", "virtualMachinePassword": "[steps('hosts').localAdminCredentials.localAdminPassword]", - "virtualMachineSize": "[if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric))))]", + "virtualMachineSize": "[if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric))))]", "virtualMachineUsername": "[steps('hosts').localAdminCredentials.localAdminUsername]", - "virtualMachineVirtualCpuCount": "[first(map(filter(first(map(filter(steps('basics').scenario.virtualMachineSkusApi.value, (item) => equals(item.name, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('controlPlane').hostPool.hostPoolType, 'Personal'), equals(steps('controlPlane').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric)))))), (item) => item.capabilities)), (item) => equals(item.name, 'vCPUs')), (item) => item.value))]", + "virtualMachineVirtualCpuCount": "[first(map(filter(first(map(filter(steps('basics').scenario.virtualMachineSkusApi.value, (item) => equals(item.name, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Pooled')), steps('hosts').virtualMachines.sizeArcGisProMulti, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 6)), steps('hosts').virtualMachines.sizeArcGisProSingleLight, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 4)), steps('hosts').virtualMachines.sizeArcGisProSingleMedium, if(and(equals(steps('basics').scenario.profile, 'arcGisPro'), equals(steps('management').hostPool.hostPoolType, 'Personal'), equals(steps('management').hostPool.workloadType, 3)), steps('hosts').virtualMachines.sizeArcGisProSingleHeavy, steps('hosts').virtualMachines.sizeGeneric)))))), (item) => item.capabilities)), (item) => equals(item.name, 'vCPUs')), (item) => item.value))]", "virtualNetworkAddressPrefixes": "[parse(concat('[\"', steps('network').vnet.virtualNetworkAddressCidrRange, '\"]'))]", - "workspaceFriendlyName": "[if(empty(first(map(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.id))), steps('controlPlane').friendlyNames.feedWorkspace, first(map(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.properties.friendlyName)))]", - "workspacePublicNetworkAccess": "[if(empty(first(map(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.id))), steps('controlPlane').workspace.publicNetworkAccess, first(map(filter(steps('controlPlane').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.properties.publicNetworkAccess)))]" + "workspaceFriendlyName": "[if(empty(first(map(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.id))), steps('management').friendlyNames.feedWorkspace, first(map(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.properties.friendlyName)))]", + "workspacePublicNetworkAccess": "[if(empty(first(map(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.id))), steps('management').workspace.publicNetworkAccess, first(map(filter(steps('management').workspacesApi.value, (item) => and(contains(item.name, steps('basics').naming.identifier), contains(item.name, 'feed'), contains(item.name, steps('basics').naming.environment), equals(item.location, steps('basics').hub.azureFirewallApi.location))), (item) => item.properties.publicNetworkAccess)))]" }, "kind": "Subscription", "location": "[steps('basics').scope.location.name]", diff --git a/src/bicep/add-ons/imaging/solution.json b/src/bicep/add-ons/imaging/solution.json index b13319935..bccc542d8 100644 --- a/src/bicep/add-ons/imaging/solution.json +++ b/src/bicep/add-ons/imaging/solution.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13460307319082964405" + "version": "0.31.92.45157", + "templateHash": "1176843216741362451" } }, "parameters": { @@ -600,8 +600,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16140764241259827428" + "version": "0.31.92.45157", + "templateHash": "14266827690996546891" } }, "parameters": { @@ -877,8 +877,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16220429751656280628" + "version": "0.31.92.45157", + "templateHash": "15810721730485220824" } }, "parameters": { @@ -957,8 +957,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3270228280505109788" + "version": "0.31.92.45157", + "templateHash": "11125044402666498605" } }, "parameters": { @@ -1410,6 +1410,7 @@ "remoteApplicationGroups": "vdag", "resourceGroups": "rg", "routeTables": "rt", + "scalingPlans": "vdscaling", "storageAccounts": "st", "subnets": "snet", "userAssignedIdentities": "id", @@ -1424,7 +1425,7 @@ "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", "names": { "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", - "applicationGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationGroups)]", + "applicationGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-desktop', variables('resourceAbbreviations').applicationGroups))]", "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", @@ -1478,6 +1479,8 @@ "recoveryServicesVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", "resourceGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').resourceGroups)]", "routeTable": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').routeTables)]", + "scalingPlan": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').scalingPlans)]", + "scalingPlanDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').scalingPlans)]", "storageAccount": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').storageAccounts), parameters('networkName'), parameters('networkShortName'))]", "storageAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').storageAccounts))]", "storageAccountBlobNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", @@ -1495,14 +1498,14 @@ "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", - "workspaceFeed": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobal": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" + "workspaceFeed": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobal": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" } }, "resources": [], @@ -1548,8 +1551,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4151572700986885014" + "version": "0.31.92.45157", + "templateHash": "17619606927129129347" } }, "parameters": { @@ -1688,8 +1691,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10109660736443081073" + "version": "0.31.92.45157", + "templateHash": "9371138343009436350" } }, "parameters": { @@ -1817,8 +1820,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2001402118470594055" + "version": "0.31.92.45157", + "templateHash": "12095518102496352105" } }, "parameters": { @@ -1953,8 +1956,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3535186238457701125" + "version": "0.31.92.45157", + "templateHash": "11818136489056939588" } }, "parameters": { @@ -2071,8 +2074,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6722359274420487391" + "version": "0.31.92.45157", + "templateHash": "3681943409502537301" } }, "parameters": { @@ -2154,8 +2157,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12652296496577802490" + "version": "0.31.92.45157", + "templateHash": "18425321023142226965" } }, "parameters": { @@ -2257,8 +2260,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17592952825859536181" + "version": "0.31.92.45157", + "templateHash": "15002544166394392504" } }, "parameters": { @@ -2334,8 +2337,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7007835755326231171" + "version": "0.31.92.45157", + "templateHash": "16817025486402215719" } }, "parameters": { @@ -2475,8 +2478,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3832300165614083813" + "version": "0.31.92.45157", + "templateHash": "10267893616110384815" } }, "parameters": { @@ -2528,8 +2531,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2015499370398293300" + "version": "0.31.92.45157", + "templateHash": "5574526676512163672" } }, "parameters": { @@ -2602,8 +2605,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9502319494004310539" + "version": "0.31.92.45157", + "templateHash": "11553909803736438916" } }, "parameters": { @@ -2655,8 +2658,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2015499370398293300" + "version": "0.31.92.45157", + "templateHash": "5574526676512163672" } }, "parameters": { @@ -2755,8 +2758,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10999644342250296299" + "version": "0.31.92.45157", + "templateHash": "4304275711041823961" } }, "parameters": { @@ -2813,8 +2816,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2757774880390840506" + "version": "0.31.92.45157", + "templateHash": "16077950968688123011" } }, "parameters": { @@ -2916,8 +2919,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11152278840466293351" + "version": "0.31.92.45157", + "templateHash": "12787329163785242553" } }, "parameters": { @@ -3005,8 +3008,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1874197755006172394" + "version": "0.31.92.45157", + "templateHash": "11761568940379970751" } }, "parameters": { @@ -3263,8 +3266,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17613382135787640077" + "version": "0.31.92.45157", + "templateHash": "4207798980384159491" } }, "parameters": { @@ -3343,8 +3346,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8372265102618018066" + "version": "0.31.92.45157", + "templateHash": "1966035938992047983" } }, "parameters": { @@ -3438,8 +3441,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6675708379514380442" + "version": "0.31.92.45157", + "templateHash": "7930493629995578222" } }, "parameters": { @@ -3596,8 +3599,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2377877844306490130" + "version": "0.31.92.45157", + "templateHash": "17358288344184718166" } }, "parameters": { @@ -3712,8 +3715,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13359240625570837130" + "version": "0.31.92.45157", + "templateHash": "1625826941635729014" } }, "parameters": { @@ -3993,8 +3996,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8480968961555779332" + "version": "0.31.92.45157", + "templateHash": "4345251511078445463" } }, "parameters": { @@ -4068,8 +4071,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8389358797157027271" + "version": "0.31.92.45157", + "templateHash": "4687229436121899773" } }, "parameters": { @@ -4158,8 +4161,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3320497816733398371" + "version": "0.31.92.45157", + "templateHash": "1721966359516622278" } }, "parameters": { @@ -4232,8 +4235,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9851134383266019486" + "version": "0.31.92.45157", + "templateHash": "2073766618455932098" } }, "parameters": { @@ -4310,8 +4313,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7358671180047253284" + "version": "0.31.92.45157", + "templateHash": "9546260853018527046" } }, "parameters": { @@ -4401,8 +4404,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7046499602359448652" + "version": "0.31.92.45157", + "templateHash": "15014526386353172066" } }, "parameters": { @@ -4458,8 +4461,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16614224552992880134" + "version": "0.31.92.45157", + "templateHash": "8545903679924437739" } }, "parameters": { @@ -4634,8 +4637,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8372265102618018066" + "version": "0.31.92.45157", + "templateHash": "1966035938992047983" } }, "parameters": { @@ -4719,8 +4722,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3588347827815061814" + "version": "0.31.92.45157", + "templateHash": "17047820191891552534" } }, "parameters": { @@ -5069,8 +5072,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "5226016669112266321" + "version": "0.31.92.45157", + "templateHash": "10919933768401588181" } }, "parameters": { @@ -5143,8 +5146,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13440676993724521939" + "version": "0.31.92.45157", + "templateHash": "18352816396611024893" } }, "parameters": { @@ -5209,8 +5212,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17072503057563414192" + "version": "0.31.92.45157", + "templateHash": "6200502377293455151" } }, "parameters": { @@ -5273,8 +5276,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15644482179055938365" + "version": "0.31.92.45157", + "templateHash": "7660308816591621829" } }, "parameters": { @@ -5332,8 +5335,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14434555555821069254" + "version": "0.31.92.45157", + "templateHash": "4828751436439954614" } }, "parameters": { @@ -5403,8 +5406,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "18308303526064452173" + "version": "0.31.92.45157", + "templateHash": "505668065736432808" } }, "parameters": { @@ -5493,8 +5496,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17898789400078556340" + "version": "0.31.92.45157", + "templateHash": "15938438919628281730" } }, "parameters": { @@ -5771,8 +5774,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "14434361731662776378" + "version": "0.31.92.45157", + "templateHash": "3864397971513159924" } }, "parameters": { @@ -6026,8 +6029,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7158084538460059744" + "version": "0.31.92.45157", + "templateHash": "10151591372092483611" } }, "parameters": { @@ -6112,8 +6115,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1996155124645705619" + "version": "0.31.92.45157", + "templateHash": "16335756069146472371" } }, "parameters": { @@ -6322,8 +6325,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2306888083293626312" + "version": "0.31.92.45157", + "templateHash": "17205876022497810397" } }, "parameters": { @@ -8410,8 +8413,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10068687414279329406" + "version": "0.31.92.45157", + "templateHash": "8601742688955831915" } }, "parameters": { @@ -8777,8 +8780,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15496706649353968351" + "version": "0.31.92.45157", + "templateHash": "4852229183946608444" } }, "parameters": { @@ -9313,8 +9316,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2877200692627316157" + "version": "0.31.92.45157", + "templateHash": "8637536946355167151" } }, "parameters": { @@ -9687,8 +9690,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10741782051085334434" + "version": "0.31.92.45157", + "templateHash": "8072924941165181371" } }, "parameters": { @@ -9961,8 +9964,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10068687414279329406" + "version": "0.31.92.45157", + "templateHash": "8601742688955831915" } }, "parameters": { @@ -10171,8 +10174,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8116252798517351972" + "version": "0.31.92.45157", + "templateHash": "6378421340828498206" } }, "parameters": { @@ -10422,8 +10425,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "885927068946767612" + "version": "0.31.92.45157", + "templateHash": "14159413360692546906" } }, "parameters": { @@ -10845,8 +10848,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13463113052745382608" + "version": "0.31.92.45157", + "templateHash": "3743593020967196481" } }, "parameters": { @@ -10948,8 +10951,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1633398337190030443" + "version": "0.31.92.45157", + "templateHash": "7677543733842229678" } }, "parameters": { @@ -11035,8 +11038,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13463113052745382608" + "version": "0.31.92.45157", + "templateHash": "3743593020967196481" } }, "parameters": { @@ -11131,8 +11134,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "15079303238971201589" + "version": "0.31.92.45157", + "templateHash": "1029512189778888686" } }, "parameters": { @@ -11212,8 +11215,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6420082476378279690" + "version": "0.31.92.45157", + "templateHash": "8843400045516737228" } }, "parameters": { @@ -11333,8 +11336,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9737618372857567001" + "version": "0.31.92.45157", + "templateHash": "5465461266607898562" } }, "parameters": { @@ -11489,8 +11492,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13012724632844552518" + "version": "0.31.92.45157", + "templateHash": "4834529006346309280" } }, "parameters": { diff --git a/src/bicep/add-ons/imaging/uiDefinition.json b/src/bicep/add-ons/imaging/uiDefinition.json index 3f07eeaf5..16a18b38a 100644 --- a/src/bicep/add-ons/imaging/uiDefinition.json +++ b/src/bicep/add-ons/imaging/uiDefinition.json @@ -1048,10 +1048,6 @@ "recommendedSizes": [ "Standard_D4ads_v5" ], - "constraints": { - "allowedSizes": [], - "numAvailabilityZonesRequired": 1 - }, "options": { "hideDiskTypeFilter": false }, diff --git a/src/bicep/add-ons/tier3/solution.json b/src/bicep/add-ons/tier3/solution.json index 43f0099ae..d155fc311 100644 --- a/src/bicep/add-ons/tier3/solution.json +++ b/src/bicep/add-ons/tier3/solution.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16140764241259827428" + "version": "0.31.92.45157", + "templateHash": "14266827690996546891" } }, "parameters": { @@ -281,8 +281,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16220429751656280628" + "version": "0.31.92.45157", + "templateHash": "15810721730485220824" } }, "parameters": { @@ -361,8 +361,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3270228280505109788" + "version": "0.31.92.45157", + "templateHash": "11125044402666498605" } }, "parameters": { @@ -814,6 +814,7 @@ "remoteApplicationGroups": "vdag", "resourceGroups": "rg", "routeTables": "rt", + "scalingPlans": "vdscaling", "storageAccounts": "st", "subnets": "snet", "userAssignedIdentities": "id", @@ -828,7 +829,7 @@ "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", "names": { "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", - "applicationGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationGroups)]", + "applicationGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-desktop', variables('resourceAbbreviations').applicationGroups))]", "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", @@ -882,6 +883,8 @@ "recoveryServicesVaultPrivateEndpoint": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, variables('resourceAbbreviations').recoveryServicesVaults)]", "resourceGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').resourceGroups)]", "routeTable": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').routeTables)]", + "scalingPlan": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').scalingPlans)]", + "scalingPlanDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').scalingPlans)]", "storageAccount": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').storageAccounts), parameters('networkName'), parameters('networkShortName'))]", "storageAccountDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').storageAccounts))]", "storageAccountBlobNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-blob', variables('resourceAbbreviations').storageAccounts))]", @@ -899,14 +902,14 @@ "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", - "workspaceFeed": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobal": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" + "workspaceFeed": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobal": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" } }, "resources": [], @@ -952,8 +955,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "4151572700986885014" + "version": "0.31.92.45157", + "templateHash": "17619606927129129347" } }, "parameters": { @@ -1092,8 +1095,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10109660736443081073" + "version": "0.31.92.45157", + "templateHash": "9371138343009436350" } }, "parameters": { @@ -1221,8 +1224,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2001402118470594055" + "version": "0.31.92.45157", + "templateHash": "12095518102496352105" } }, "parameters": { @@ -1357,8 +1360,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3535186238457701125" + "version": "0.31.92.45157", + "templateHash": "11818136489056939588" } }, "parameters": { @@ -1475,8 +1478,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6722359274420487391" + "version": "0.31.92.45157", + "templateHash": "3681943409502537301" } }, "parameters": { @@ -1558,8 +1561,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "12652296496577802490" + "version": "0.31.92.45157", + "templateHash": "18425321023142226965" } }, "parameters": { @@ -1661,8 +1664,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17592952825859536181" + "version": "0.31.92.45157", + "templateHash": "15002544166394392504" } }, "parameters": { @@ -1738,8 +1741,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7007835755326231171" + "version": "0.31.92.45157", + "templateHash": "16817025486402215719" } }, "parameters": { @@ -1879,8 +1882,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3832300165614083813" + "version": "0.31.92.45157", + "templateHash": "10267893616110384815" } }, "parameters": { @@ -1932,8 +1935,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2015499370398293300" + "version": "0.31.92.45157", + "templateHash": "5574526676512163672" } }, "parameters": { @@ -2006,8 +2009,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9502319494004310539" + "version": "0.31.92.45157", + "templateHash": "11553909803736438916" } }, "parameters": { @@ -2059,8 +2062,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2015499370398293300" + "version": "0.31.92.45157", + "templateHash": "5574526676512163672" } }, "parameters": { @@ -2159,8 +2162,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "10999644342250296299" + "version": "0.31.92.45157", + "templateHash": "4304275711041823961" } }, "parameters": { @@ -2217,8 +2220,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2757774880390840506" + "version": "0.31.92.45157", + "templateHash": "16077950968688123011" } }, "parameters": { @@ -2320,8 +2323,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "11152278840466293351" + "version": "0.31.92.45157", + "templateHash": "12787329163785242553" } }, "parameters": { @@ -2409,8 +2412,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "1874197755006172394" + "version": "0.31.92.45157", + "templateHash": "11761568940379970751" } }, "parameters": { @@ -2667,8 +2670,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "17613382135787640077" + "version": "0.31.92.45157", + "templateHash": "4207798980384159491" } }, "parameters": { @@ -2747,8 +2750,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8372265102618018066" + "version": "0.31.92.45157", + "templateHash": "1966035938992047983" } }, "parameters": { @@ -2842,8 +2845,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "6675708379514380442" + "version": "0.31.92.45157", + "templateHash": "7930493629995578222" } }, "parameters": { @@ -3000,8 +3003,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "2377877844306490130" + "version": "0.31.92.45157", + "templateHash": "17358288344184718166" } }, "parameters": { @@ -3116,8 +3119,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "13359240625570837130" + "version": "0.31.92.45157", + "templateHash": "1625826941635729014" } }, "parameters": { @@ -3397,8 +3400,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8480968961555779332" + "version": "0.31.92.45157", + "templateHash": "4345251511078445463" } }, "parameters": { @@ -3472,8 +3475,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8389358797157027271" + "version": "0.31.92.45157", + "templateHash": "4687229436121899773" } }, "parameters": { @@ -3562,8 +3565,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3320497816733398371" + "version": "0.31.92.45157", + "templateHash": "1721966359516622278" } }, "parameters": { @@ -3636,8 +3639,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "9851134383266019486" + "version": "0.31.92.45157", + "templateHash": "2073766618455932098" } }, "parameters": { @@ -3714,8 +3717,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7358671180047253284" + "version": "0.31.92.45157", + "templateHash": "9546260853018527046" } }, "parameters": { @@ -3805,8 +3808,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "7046499602359448652" + "version": "0.31.92.45157", + "templateHash": "15014526386353172066" } }, "parameters": { @@ -3862,8 +3865,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "16614224552992880134" + "version": "0.31.92.45157", + "templateHash": "8545903679924437739" } }, "parameters": { @@ -4038,8 +4041,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "8372265102618018066" + "version": "0.31.92.45157", + "templateHash": "1966035938992047983" } }, "parameters": { @@ -4123,8 +4126,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.30.23.60470", - "templateHash": "3588347827815061814" + "version": "0.31.92.45157", + "templateHash": "17047820191891552534" } }, "parameters": { diff --git a/src/bicep/mlz.json b/src/bicep/mlz.json index 105425e42..df9569d57 100644 --- a/src/bicep/mlz.json +++ b/src/bicep/mlz.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.31.92.45157", - "templateHash": "7670256562437793548" + "templateHash": "4662751976093611386" } }, "parameters": { @@ -888,7 +888,7 @@ "_generator": { "name": "bicep", "version": "0.31.92.45157", - "templateHash": "4114664614478275863" + "templateHash": "15810721730485220824" } }, "parameters": { @@ -968,7 +968,7 @@ "_generator": { "name": "bicep", "version": "0.31.92.45157", - "templateHash": "6411408920489493501" + "templateHash": "11125044402666498605" } }, "parameters": { @@ -1435,7 +1435,7 @@ "namingConvention_Service": "[format('{0}-{1}{2}-{3}-{4}-{5}-{6}', toLower(parameters('resourcePrefix')), if(empty(parameters('stampIndex')), '', format('{0}-', parameters('stampIndex'))), parameters('tokens').resource, parameters('networkName'), parameters('tokens').service, variables('locationAbbreviation'), parameters('environmentAbbreviation'))]", "names": { "actionGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').actionGroups)]", - "applicationGroup": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationGroups)]", + "applicationGroup": "[replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-desktop', variables('resourceAbbreviations').applicationGroups))]", "applicationInsights": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').applicationInsights)]", "appServicePlan": "[replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').appServicePlans)]", "automationAccount": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').automationAccounts)]", @@ -1508,14 +1508,14 @@ "virtualMachineNetworkInterface": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').virtualMachines))]", "virtualNetwork": "[replace(variables('namingConvention'), parameters('tokens').resource, variables('resourceAbbreviations').virtualNetworks)]", "virtualNetworkDiagnosticSetting": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, variables('resourceAbbreviations').virtualNetworks)]", - "workspaceFeed": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobal": "[replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').workspaces), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", - "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-{1}', parameters('tokens').service, variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" + "workspaceFeed": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceFeedPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-feed', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobal": "[replace(replace(variables('namingConvention'), parameters('tokens').resource, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalDiagnosticSetting": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').diagnosticSettings), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalNetworkInterface": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').networkInterfaces), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]", + "workspaceGlobalPrivateEndpoint": "[replace(replace(replace(variables('namingConvention_Service'), parameters('tokens').resource, variables('resourceAbbreviations').privateEndpoints), parameters('tokens').service, format('{0}-global', variables('resourceAbbreviations').workspaces)), format('-{0}', parameters('stampIndex')), '')]" } }, "resources": [], diff --git a/src/bicep/modules/naming-convention.bicep b/src/bicep/modules/naming-convention.bicep index 0a2680fea..b9b746e22 100644 --- a/src/bicep/modules/naming-convention.bicep +++ b/src/bicep/modules/naming-convention.bicep @@ -51,7 +51,7 @@ var namingConvention_Service = '${toLower(resourcePrefix)}-${empty(stampIndex) ? var names = { actionGroup: replace(namingConvention, tokens.resource, resourceAbbreviations.actionGroups) - applicationGroup: replace(namingConvention_Service, tokens.resource, resourceAbbreviations.applicationGroups) + applicationGroup: replace(namingConvention, tokens.resource, '${resourceAbbreviations.applicationGroups}-desktop') applicationInsights: replace(namingConvention_Service, tokens.resource, resourceAbbreviations.applicationInsights) appServicePlan: replace(namingConvention_Service, tokens.resource, resourceAbbreviations.appServicePlans) automationAccount: replace(namingConvention, tokens.resource, resourceAbbreviations.automationAccounts) @@ -124,14 +124,14 @@ var names = { virtualMachineNetworkInterface: replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.networkInterfaces), tokens.service, '${tokens.service}-${resourceAbbreviations.virtualMachines}') virtualNetwork: replace(namingConvention, tokens.resource, resourceAbbreviations.virtualNetworks) virtualNetworkDiagnosticSetting: replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.diagnosticSettings), tokens.service, resourceAbbreviations.virtualNetworks) - workspaceFeed: replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.workspaces), '-${stampIndex}', '') - workspaceFeedDiagnosticSetting: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.diagnosticSettings), tokens.service, '${tokens.service}-${resourceAbbreviations.workspaces}'), '-${stampIndex}', '') - workspaceFeedNetworkInterface: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.networkInterfaces), tokens.service, '${tokens.service}-${resourceAbbreviations.workspaces}'), '-${stampIndex}', '') - workspaceFeedPrivateEndpoint: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.privateEndpoints), tokens.service, '${tokens.service}-${resourceAbbreviations.workspaces}'), '-${stampIndex}', '') - workspaceGlobal: replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.workspaces), '-${stampIndex}', '') - workspaceGlobalDiagnosticSetting: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.diagnosticSettings), tokens.service, '${tokens.service}-${resourceAbbreviations.workspaces}'), '-${stampIndex}', '') - workspaceGlobalNetworkInterface: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.networkInterfaces), tokens.service, '${tokens.service}-${resourceAbbreviations.workspaces}'), '-${stampIndex}', '') - workspaceGlobalPrivateEndpoint: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.privateEndpoints), tokens.service, '${tokens.service}-${resourceAbbreviations.workspaces}'), '-${stampIndex}', '') + workspaceFeed: replace(replace(namingConvention, tokens.resource, '${resourceAbbreviations.workspaces}-feed'), '-${stampIndex}', '') + workspaceFeedDiagnosticSetting: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.diagnosticSettings), tokens.service, '${resourceAbbreviations.workspaces}-feed'), '-${stampIndex}', '') + workspaceFeedNetworkInterface: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.networkInterfaces), tokens.service, '${resourceAbbreviations.workspaces}-feed'), '-${stampIndex}', '') + workspaceFeedPrivateEndpoint: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.privateEndpoints), tokens.service, '${resourceAbbreviations.workspaces}-feed'), '-${stampIndex}', '') + workspaceGlobal: replace(replace(namingConvention, tokens.resource, '${resourceAbbreviations.workspaces}-global'), '-${stampIndex}', '') + workspaceGlobalDiagnosticSetting: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.diagnosticSettings), tokens.service, '${resourceAbbreviations.workspaces}-global'), '-${stampIndex}', '') + workspaceGlobalNetworkInterface: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.networkInterfaces), tokens.service, '${resourceAbbreviations.workspaces}-global'), '-${stampIndex}', '') + workspaceGlobalPrivateEndpoint: replace(replace(replace(namingConvention_Service, tokens.resource, resourceAbbreviations.privateEndpoints), tokens.service, '${resourceAbbreviations.workspaces}-global'), '-${stampIndex}', '') } output locations object = locations