From 48c82d830214325a555795995f76bcd8ffd2e093 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Fri, 24 Jun 2022 14:07:53 -0700 Subject: [PATCH 01/17] Created Bicep files and removed all errors, need a few comments resolved before implementing. --- .../AddVirtualMachinesTemplate.bicep | 326 ++++++++++ .../CreateHostpoolTemplate.bicep | 569 ++++++++++++++++++ .../managedDisks-customimagevm.bicep | 350 +++++++++++ .../managedDisks-customvhdvm.bicep | 366 +++++++++++ .../managedDisks-galleryvm.bicep | 355 +++++++++++ ...ed_AVSet_linkedTemplate_deploymentId.bicep | 56 ++ .../nested_NSG_linkedTemplate.bicep | 14 + .../nested_UpdateHostPool_deploymentId.bicep | 14 + ...orkspace_linkedTemplate_deploymentId.bicep | 12 + .../nested_newNsgDeploymentName.bicep | 22 + .../unmanagedDisks-customvhdvm.bicep | 345 +++++++++++ 11 files changed, 2429 insertions(+) create mode 100644 bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep create mode 100644 bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep create mode 100644 bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep create mode 100644 bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep create mode 100644 bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep create mode 100644 bicep-templates/nestedtemplates/nested_AVSet_linkedTemplate_deploymentId.bicep create mode 100644 bicep-templates/nestedtemplates/nested_NSG_linkedTemplate.bicep create mode 100644 bicep-templates/nestedtemplates/nested_UpdateHostPool_deploymentId.bicep create mode 100644 bicep-templates/nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep create mode 100644 bicep-templates/nestedtemplates/nested_newNsgDeploymentName.bicep create mode 100644 bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep diff --git a/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep b/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep new file mode 100644 index 000000000..4d7e72b7a --- /dev/null +++ b/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep @@ -0,0 +1,326 @@ +@description('The base URI where artifacts required by this template are located.') +param nestedTemplatesLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/nestedtemplates/' + +@description('The base URI where artifacts required by this template are located.') +param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' + +@description('The name of the Hostpool to be created.') +param hostpoolName string + +@description('The token of the host pool where the session hosts will be added.') +@secure() +param hostpoolToken string + +@description('The resource group of the host pool to be updated. Used when the host pool was created empty.') +param hostpoolResourceGroup string = '' + +@description('The location of the host pool to be updated. Used when the host pool was created empty.') +param hostpoolLocation string = '' + +@description('The properties of the Hostpool to be updated. Used when the host pool was created empty.') +param hostpoolProperties object = { +} + +@description('The host pool VM template. Used when the host pool was created empty.') +param vmTemplate string = '' + +@description('A username in the domain that has privileges to join the session hosts to the domain. For example, \'vmjoiner@contoso.com\'.') +param administratorAccountUsername string = '' + +@description('The password that corresponds to the existing domain username.') +@secure() +param administratorAccountPassword string = '' + +@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +param vmAdministratorAccountUsername string = '' + +@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +@secure() +param vmAdministratorAccountPassword string = '' + +@description('Select the availability options for the VMs.') +@allowed([ + 'None' + 'AvailabilitySet' + 'AvailabilityZone' +]) +param availabilityOption string = 'None' + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string = '' + +@description('Whether to create a new availability set for the VMs.') +param createAvailabilitySet bool = false + +@description('The platform update domain count of avaiability set to be created.') +@allowed([ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +]) +param availabilitySetUpdateDomainCount int = 5 + +@description('The platform fault domain count of avaiability set to be created.') +@allowed([ + 1 + 2 + 3 +]) +param availabilitySetFaultDomainCount int = 2 + +@description('The number of availability zone to be used when create the VMs.') +@allowed([ + 1 + 2 + 3 +]) +param availabilityZone int = 1 + +@description('The resource group of the session host VMs.') +param vmResourceGroup string + +@description('The location of the session host VMs.') +param vmLocation string + +@description('The size of the session host VMs.') +param vmSize string + +@description('VM name prefix initial number.') +param vmInitialNumber int + +@description('Number of session hosts that will be created and added to the hostpool.') +param vmNumberOfInstances int + +@description('This prefix will be used in combination with the VM number to create the VM name. If using \'rdsh\' as the prefix, VMs would be named \'rdsh-0\', \'rdsh-1\', etc. You should use a unique prefix to reduce name collisions in Active Directory.') +param vmNamePrefix string + +@description('Select the image source for the session host vms. VMs from a Gallery image will be created with Managed Disks.') +@allowed([ + 'CustomVHD' + 'CustomImage' + 'Gallery' + 'Disk' +]) +param vmImageType string = 'Gallery' + +@description('(Required when vmImageType = Gallery) Gallery image Offer.') +param vmGalleryImageOffer string = '' + +@description('(Required when vmImageType = Gallery) Gallery image Publisher.') +param vmGalleryImagePublisher string = '' + +@description('(Required when vmImageType = Gallery) Gallery image SKU.') +param vmGalleryImageSKU string = '' + +@description('(Required when vmImageType = Gallery) Gallery image version.') +param vmGalleryImageVersion string = '' + +@description('Whether the VM has plan or not') +param vmGalleryImageHasPlan bool = false + +@description('(Required when vmImageType = CustomVHD) URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') +param vmImageVhdUri string = '' + +@description('(Required when vmImageType = CustomImage) Resource ID of the image') +param vmCustomImageSourceId string = '' + +@description('The VM disk type for the VM: HDD or SSD.') +@allowed([ + 'UltraSSD_LRS' + 'Premium_LRS' + 'StandardSSD_LRS' + 'Standard_LRS' +]) +param vmDiskType string + +@description('True indicating you would like to use managed disks or false indicating you would like to use unmanaged disks.') +param vmUseManagedDisks bool + +@description('(Required when vmUseManagedDisks = False) The resource group containing the storage account of the image vhd file.') +param storageAccountResourceGroupName string = '' + +@description('The name of the virtual network the VMs will be connected to.') +param existingVnetName string + +@description('The subnet the VMs will be placed in.') +param existingSubnetName string + +@description('The resource group containing the existing virtual network.') +param virtualNetworkResourceGroupName string + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool = false + +@description('The resource id of an existing network security group') +param networkSecurityGroupId string = '' + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array = [] + +@description('The tags to be assigned to the availability set') +param availabilitySetTags object = { +} + +@description('The tags to be assigned to the network interfaces') +param networkInterfaceTags object = { +} + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object = { +} + +@description('The tags to be assigned to the virtual machines') +param virtualMachineTags object = { +} + +@description('The tags to be assigned to the images') +param imageTags object = { +} + +@description('GUID for the deployment') +param deploymentId string = '' + +@description('WVD api version') +param apiVersion string = '2019-12-10-preview' + +@description('OUPath for the domain join') +param ouPath string = '' + +@description('Domain to join') +param domain string = '' + +@description('True if AAD Join, false if AD join') +param aadJoin bool = false + +@description('True if intune enrollment is selected. False otherwise') +param intune bool = false + +@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') +param bootDiagnostics object = { + enabled: false +} + +@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') +param userAssignedIdentity string = '' + +@description('ARM template that contains custom configurations to be run after the virtual machines are created.') +param customConfigurationTemplateUrl string = '' + +@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') +param customConfigurationParameterUrl string = '' + +@description('System data is used for internal purposes, such as support preview features.') +param systemData object = { +} + +var rdshManagedDisks = ((vmImageType == 'CustomVHD') ? vmUseManagedDisks : bool('true')) +var rdshPrefix = '${vmNamePrefix}-' +var avSetSKU = (rdshManagedDisks ? 'Aligned' : 'Classic') +var vhds = 'vhds/${rdshPrefix}' +var subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) +var vmTemplateName = '${(rdshManagedDisks ? 'managedDisks' : 'unmanagedDisks')}-${toLower(replace(vmImageType, ' ', ''))}vm' +var vmTemplateUri = '${nestedTemplatesLocation}${vmTemplateName}.json' +var rdshVmNamesCopyNamesArr = [for item in range(0, (vmNumberOfInstances)): { + name: '${rdshPrefix}${vmInitialNumber + item}' +}] +var rdshVmNamesOutput = { + rdshVmNamesCopy: rdshVmNamesCopyNamesArr +} +module UpdateHostPool_deploymentId '../nestedtemplates/nested_UpdateHostPool_deploymentId.bicep' = if (!empty(hostpoolResourceGroup)) { + name: 'UpdateHostPool-${deploymentId}' + scope: resourceGroup(hostpoolResourceGroup) + params: { + hostpoolName: hostpoolName + hostpoolLocation: hostpoolLocation + hostpoolProperties: hostpoolProperties + } +} + +module AVSet_linkedTemplate_deploymentId '../nestedtemplates/nested_AVSet_linkedTemplate_deploymentId.bicep' = if ((availabilityOption == 'AvailabilitySet') && createAvailabilitySet) { + name: 'AVSet-linkedTemplate-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + avSetSKU: avSetSKU + availabilitySetName: availabilitySetName + vmLocation: vmLocation + availabilitySetTags: availabilitySetTags + availabilitySetUpdateDomainCount: availabilitySetUpdateDomainCount + availabilitySetFaultDomainCount: availabilitySetFaultDomainCount + } + dependsOn: [ + UpdateHostPool_deploymentId + ] +} +/*TODO: replace with correct path to [variables('vmTemplateUri')] Bicep currently does not "support string interpolation in FilePaths." This is going to require some deeper refactoring, Either by using BICEP PUBLISH, or keeping local copy in the GitHub repo.*/ +module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json locally to my build and convert to bicep only for workaround, ask preference next meeting*/ = { + name: 'vmCreation-linkedTemplate-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + 'subnet-id': subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + vmInitialNumber: vmInitialNumber + hostpoolName: hostpoolName + hostpoolToken: hostpoolToken + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + '_guidValue': deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: (contains(systemData, 'hostpoolUpdate') ? systemData.sessionHostConfigurationVersion : '') + } + dependsOn: [ + AVSet_linkedTemplate_deploymentId + ] +} + +output rdshVmNamesObject object = rdshVmNamesOutput diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep new file mode 100644 index 000000000..3b562b0e1 --- /dev/null +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -0,0 +1,569 @@ +@description('The base URI where artifacts required by this template are located.') +param nestedTemplatesLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/nestedtemplates/' + +@description('The base URI where artifacts required by this template are located.') +param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' + +@description('The name of the Hostpool to be created.') +param hostpoolName string + +@description('The friendly name of the Hostpool to be created.') +param hostpoolFriendlyName string = '' + +@description('The description of the Hostpool to be created.') +param hostpoolDescription string = '' + +@description('The storage uri to put the diagnostic logs') +param hostpoolDiagnosticSettingsStorageAccount string = '' + +@description('The description of the Hostpool to be created.') +param hostpoolDiagnosticSettingsLogAnalyticsWorkspaceId string = '' + +@description('The event hub name to send logs to') +param hostpoolDiagnosticSettingsEventHubName string = '' + +@description('The event hub policy to use') +param hostpoolDiagnosticSettingsEventHubAuthorizationId string = '' + +@description('Categories of logs to be created for hostpools') +param hostpoolDiagnosticSettingsLogCategories array = [ + 'Checkpoint' + 'Error' + 'Management' + 'Connection' + 'HostRegistration' + 'AgentHealthStatus' +] + +@description('Categories of logs to be created for app groups') +param appGroupDiagnosticSettingsLogCategories array = [ + 'Checkpoint' + 'Error' + 'Management' +] + +@description('Categories of logs to be created for workspaces') +param workspaceDiagnosticSettingsLogCategories array = [ + 'Checkpoint' + 'Error' + 'Management' + 'Feed' +] + +@description('The location where the resources will be deployed.') +param location string + +@description('The name of the workspace to be attach to new Applicaiton Group.') +param workSpaceName string = '' + +@description('The location of the workspace.') +param workspaceLocation string = '' + +@description('The workspace resource group Name.') +param workspaceResourceGroup string = '' + +@description('True if the workspace is new. False if there is no workspace added or adding to an existing workspace.') +param isNewWorkspace bool = false + +@description('The existing app groups references of the workspace selected.') +param allApplicationGroupReferences string = '' + +@description('Whether to add applicationGroup to workspace.') +param addToWorkspace bool + +@description('A username in the domain that has privileges to join the session hosts to the domain. For example, \'vmjoiner@contoso.com\'.') +param administratorAccountUsername string = '' + +@description('The password that corresponds to the existing domain username.') +@secure() +param administratorAccountPassword string = '' + +@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +param vmAdministratorAccountUsername string = '' + +@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +@secure() +param vmAdministratorAccountPassword string = '' + +@description('Select the availability options for the VMs.') +@allowed([ + 'None' + 'AvailabilitySet' + 'AvailabilityZone' +]) +param availabilityOption string = 'None' + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string = '' + +@description('Whether to create a new availability set for the VMs.') +param createAvailabilitySet bool = false + +@description('The platform update domain count of avaiability set to be created.') +@allowed([ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +]) +param availabilitySetUpdateDomainCount int = 5 + +@description('The platform fault domain count of avaiability set to be created.') +@allowed([ + 1 + 2 + 3 +]) +param availabilitySetFaultDomainCount int = 2 + +@description('The number of availability zone to be used when create the VMs.') +@allowed([ + 1 + 2 + 3 +]) +param availabilityZone int = 1 + +@description('The resource group of the session host VMs.') +param vmResourceGroup string = '' + +@description('The location of the session host VMs.') +param vmLocation string = '' + +@description('The size of the session host VMs.') +param vmSize string = '' + +@description('Number of session hosts that will be created and added to the hostpool.') +param vmNumberOfInstances int = 0 + +@description('This prefix will be used in combination with the VM number to create the VM name. If using \'rdsh\' as the prefix, VMs would be named \'rdsh-0\', \'rdsh-1\', etc. You should use a unique prefix to reduce name collisions in Active Directory.') +param vmNamePrefix string = '' + +@description('Select the image source for the session host vms. VMs from a Gallery image will be created with Managed Disks.') +@allowed([ + 'CustomVHD' + 'CustomImage' + 'Gallery' +]) +param vmImageType string = 'Gallery' + +@description('(Required when vmImageType = Gallery) Gallery image Offer.') +param vmGalleryImageOffer string = '' + +@description('(Required when vmImageType = Gallery) Gallery image Publisher.') +param vmGalleryImagePublisher string = '' + +@description('Whether the VM has plan or not') +param vmGalleryImageHasPlan bool = false + +@description('(Required when vmImageType = Gallery) Gallery image SKU.') +param vmGalleryImageSKU string = '' + +@description('(Required when vmImageType = Gallery) Gallery image version.') +param vmGalleryImageVersion string = '' + +@description('(Required when vmImageType = CustomVHD) URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') +param vmImageVhdUri string = '' + +@description('(Required when vmImageType = CustomImage) Resource ID of the image') +param vmCustomImageSourceId string = '' + +@description('The VM disk type for the VM: HDD or SSD.') +@allowed([ + 'Premium_LRS' + 'StandardSSD_LRS' + 'Standard_LRS' +]) +param vmDiskType string = 'StandardSSD_LRS' + +@description('True indicating you would like to use managed disks or false indicating you would like to use unmanaged disks.') +param vmUseManagedDisks bool = true + +@description('(Required when vmUseManagedDisks = False) The resource group containing the storage account of the image vhd file.') +param storageAccountResourceGroupName string = '' + +@description('The name of the virtual network the VMs will be connected to.') +param existingVnetName string = '' + +@description('The subnet the VMs will be placed in.') +param existingSubnetName string = '' + +@description('The resource group containing the existing virtual network.') +param virtualNetworkResourceGroupName string = '' + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool = false + +@description('The resource id of an existing network security group') +param networkSecurityGroupId string = '' + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array = [] + +@description('Set this parameter to Personal if you would like to enable Persistent Desktop experience. Defaults to false.') +@allowed([ + 'Personal' + 'Pooled' +]) +param hostpoolType string + +@description('Set the type of assignment for a Personal hostpool type') +@allowed([ + 'Automatic' + 'Direct' + '' +]) +param personalDesktopAssignmentType string = '' + +@description('Maximum number of sessions.') +param maxSessionLimit int = 99999 + +@description('Type of load balancer algorithm.') +@allowed([ + 'BreadthFirst' + 'DepthFirst' + 'Persistent' +]) +param loadBalancerType string = 'BreadthFirst' + +@description('Hostpool rdp properties') +param customRdpProperty string = '' + +@description('The necessary information for adding more VMs to this Hostpool') +param vmTemplate string = '' + +@description('Hostpool token expiration time') +param tokenExpirationTime string + +@description('The tags to be assigned to the hostpool') +param hostpoolTags object = { +} + +@description('The tags to be assigned to the application group') +param applicationGroupTags object = { +} + +@description('The tags to be assigned to the availability set') +param availabilitySetTags object = { +} + +@description('The tags to be assigned to the network interfaces') +param networkInterfaceTags object = { +} + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object = { +} + +@description('The tags to be assigned to the virtual machines') +param virtualMachineTags object = { +} + +@description('The tags to be assigned to the images') +param imageTags object = { +} + +@description('WVD api version') +param apiVersion string = '2019-12-10-preview' + +@description('GUID for the deployment') +param deploymentId string = '' + +@description('Whether to use validation enviroment.') +param validationEnvironment bool = false + +@description('Preferred App Group type to display') +param preferredAppGroupType string = 'Desktop' + +@description('OUPath for the domain join') +param ouPath string = '' + +@description('Domain to join') +param domain string = '' + +@description('True if AAD Join, false if AD join') +param aadJoin bool = false + +@description('True if intune enrollment is selected. False otherwise') +param intune bool = false + +@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') +param bootDiagnostics object = { + enabled: false +} + +@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') +param userAssignedIdentity string = '' + +@description('Arm template that contains custom configurations to be run after the Virtual Machines are created.') +param customConfigurationTemplateUrl string = '' + +@description('Url to the Arm template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') +param customConfigurationParameterUrl string = '' + +@description('System data is used for internal purposes, such as support preview features.') +param systemData object = { +} + +var createVMs = (vmNumberOfInstances > 0) +var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) +var rdshManagedDisks = ((vmImageType == 'CustomVHD') ? vmUseManagedDisks : bool('true')) +var rdshPrefix = '${vmNamePrefix}-' +var avSetSKU = (rdshManagedDisks ? 'Aligned' : 'Classic') +var vhds = 'vhds/${rdshPrefix}' +var subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) +var hostpoolName_var = replace(hostpoolName, '"', '') +var vmTemplateName = '${(rdshManagedDisks ? 'managedDisks' : 'unmanagedDisks')}-${toLower(replace(vmImageType, ' ', ''))}vm' +var vmTemplateUri = '${nestedTemplatesLocation}${vmTemplateName}.json' +var rdshVmNamesCopyNamesArr = [for item in range(0, (createVMs ? vmNumberOfInstances : 1)): { + name: '${rdshPrefix}${item}' +}] +var rdshVmNamesOutput = { + rdshVmNamesCopy: rdshVmNamesCopyNamesArr +} +var appGroupName_var = '${hostpoolName_var}-DAG' +var appGroupResourceId = [ + appGroupName.id +] +var workspaceResourceGroup_var = (empty(workspaceResourceGroup) ? resourceGroup().name : workspaceResourceGroup) +var applicationGroupReferencesArr = (('' == allApplicationGroupReferences) ? appGroupResourceId : concat(split(allApplicationGroupReferences, ','), appGroupResourceId)) +var hostpoolRequiredProps = { + friendlyName: hostpoolFriendlyName + description: hostpoolDescription + hostpoolType: hostpoolType + personalDesktopAssignmentType: personalDesktopAssignmentType + maxSessionLimit: maxSessionLimit + loadBalancerType: loadBalancerType + validationEnvironment: validationEnvironment + preferredAppGroupType: preferredAppGroupType + ring: null + registrationInfo: { + expirationTime: tokenExpirationTime + token: null + registrationTokenOperation: 'Update' + } + vmTemplate: vmTemplate +} +var hostpoolOptionalProps = { + customRdpProperty: customRdpProperty +} +var sessionHostConfigurationImageMarketPlaceInfoProps = { + publisher: vmGalleryImagePublisher + offer: vmGalleryImageOffer + sku: vmGalleryImageSKU + exactVersion: vmGalleryImageVersion +} +var sendLogsToStorageAccount = (!empty(hostpoolDiagnosticSettingsStorageAccount)) +var sendLogsToLogAnalytics = (!empty(hostpoolDiagnosticSettingsLogAnalyticsWorkspaceId)) +var sendLogsToEventHub = (!empty(hostpoolDiagnosticSettingsEventHubName)) +var storageAccountIdProperty = (sendLogsToStorageAccount ? hostpoolDiagnosticSettingsStorageAccount : null) +var hostpoolDiagnosticSettingsLogProperties = [for item in hostpoolDiagnosticSettingsLogCategories: { + category: item + enabled: true + retentionPolicy: { + enabled: true + days: 30 + } +}] +var appGroupDiagnosticSettingsLogProperties = [for item in appGroupDiagnosticSettingsLogCategories: { + category: item + enabled: true + retentionPolicy: { + enabled: true + days: 30 + } +}] +var workspaceDiagnosticSettingsLogProperties = [for item in workspaceDiagnosticSettingsLogCategories: { + category: item + enabled: true + retentionPolicy: { + enabled: true + days: 30 + } +}] + +resource hostpoolName_resource 'Microsoft.DesktopVirtualization/hostpools@2019-12-10-preview' = { + name: hostpoolName + location: location + tags: hostpoolTags + properties: (empty(customRdpProperty) ? hostpoolRequiredProps : union(hostpoolOptionalProps, hostpoolRequiredProps)) +} +/*TODO: Is this type valid? It doesn't exist in Microsoft.DesktopVirtualization, but it is also referenced in the ARM template*/ +resource hostpoolName_default 'Microsoft.DesktopVirtualization/hostpools/sessionHostConfigurations@2019-12-10-preview' = if (createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) { + name: '${hostpoolName}/default' + properties: { + vMSizeId: vmSize + diskType: vmDiskType + vmCustomConfigurationUri: (empty(customConfigurationTemplateUrl) ? null : customConfigurationTemplateUrl) + vmCustomConfigurationParameterUri: (empty(customConfigurationParameterUrl) ? null : customConfigurationParameterUrl) + imageInfo: { + type: ((vmImageType == 'CustomVHD') ? 'StorageBlob' : vmImageType) + marketPlaceInfo: ((vmImageType == 'Gallery') ? sessionHostConfigurationImageMarketPlaceInfoProps : null) + storageBlobUri: ((vmImageType == 'CustomVHD') ? vmImageVhdUri : null) + customId: ((vmImageType == 'CustomImage') ? vmCustomImageSourceId : null) + } + domainInfo: { + name: domain_var + joinType: (aadJoin ? 'AzureActiveDirectory' : 'ActiveDirectory') + mdmProviderGuid: (intune ? '0000000a-0000-0000-c000-000000000000' : null) + } + } + dependsOn: [ + hostpoolName_resource + ] +} + +resource appGroupName 'Microsoft.DesktopVirtualization/applicationgroups@2019-12-10-preview' = { + name: appGroupName_var + location: location + tags: applicationGroupTags + properties: { + hostPoolArmPath: hostpoolName_resource.id + friendlyName: 'Default Desktop' + description: 'Desktop Application Group created through the Hostpool Wizard' + applicationGroupType: 'Desktop' + } +} + +module Workspace_linkedTemplate_deploymentId '..//nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep' = if (addToWorkspace) { + name: 'Workspace-linkedTemplate-${deploymentId}' + scope: resourceGroup(workspaceResourceGroup_var) + params: { + applicationGroupReferencesArr: applicationGroupReferencesArr + workSpaceName: workSpaceName + workspaceLocation: workspaceLocation + } +} + +module AVSet_linkedTemplate_deploymentId '../nestedtemplates/nested_AVSet_linkedTemplate_deploymentId.bicep' = if (createVMs && (availabilityOption == 'AvailabilitySet') && createAvailabilitySet) { + name: 'AVSet-linkedTemplate-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + avSetSKU: avSetSKU + availabilitySetName: availabilitySetName + vmLocation: vmLocation + availabilitySetTags: availabilitySetTags + availabilitySetUpdateDomainCount: availabilitySetUpdateDomainCount + availabilitySetFaultDomainCount: availabilitySetFaultDomainCount + } + dependsOn: [ + appGroupName + ] +} + +/*TODO: replace with correct path to [variables('vmTemplateUri')] Bicep currently does not "support string interpolation in FilePaths." This is going to require some deeper refactoring, Either by using BICEP PUBLISH, or keeping local copy in the GitHub repo.*/ +module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json locally to my build and convert to bicep only for workaround, ask preference next meeting*/ = if (createVMs) { + name: 'vmCreation-linkedTemplate-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + 'subnet-id': subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + hostpoolToken: hostpoolName_resource.properties.registrationInfo.token + hostpoolName: hostpoolName + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + '_guidValue': deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') + } + dependsOn: [ + AVSet_linkedTemplate_deploymentId + ] +} + +resource hostpoolName_Microsoft_Insights_diagnosticSetting 'Microsoft.DesktopVirtualization/hostpools/providers/diagnosticSettings@2017-05-01-preview' = if (sendLogsToEventHub || sendLogsToLogAnalytics || sendLogsToStorageAccount) { + location: location + name: '${hostpoolName}/Microsoft.Insights/diagnosticSetting' + properties: { + storageAccountId: (sendLogsToStorageAccount ? storageAccountIdProperty : null) + eventHubAuthorizationRuleId: (sendLogsToEventHub ? hostpoolDiagnosticSettingsEventHubAuthorizationId : null) + eventHubName: (sendLogsToEventHub ? hostpoolDiagnosticSettingsEventHubName : null) + workspaceId: (sendLogsToLogAnalytics ? hostpoolDiagnosticSettingsLogAnalyticsWorkspaceId : null) + logs: hostpoolDiagnosticSettingsLogProperties + } + dependsOn: [ + hostpoolName_resource + ] +} + +resource appGroupName_Microsoft_Insights_diagnosticSetting 'Microsoft.DesktopVirtualization/applicationgroups/providers/diagnosticSettings@2017-05-01-preview' = if (sendLogsToEventHub || sendLogsToLogAnalytics || sendLogsToStorageAccount) { + location: location + name: '${appGroupName_var}/Microsoft.Insights/diagnosticSetting' + properties: { + storageAccountId: (sendLogsToStorageAccount ? storageAccountIdProperty : null) + eventHubAuthorizationRuleId: (sendLogsToEventHub ? hostpoolDiagnosticSettingsEventHubAuthorizationId : null) + eventHubName: (sendLogsToEventHub ? hostpoolDiagnosticSettingsEventHubName : null) + workspaceId: (sendLogsToLogAnalytics ? hostpoolDiagnosticSettingsLogAnalyticsWorkspaceId : null) + logs: appGroupDiagnosticSettingsLogProperties + } + dependsOn: [ + appGroupName + ] +} + +resource isNewWorkspace_workSpaceName_placeholder_Microsoft_Insights_diagnosticSetting 'Microsoft.DesktopVirtualization/workspaces/providers/diagnosticSettings@2017-05-01-preview' = if (isNewWorkspace && (sendLogsToEventHub || sendLogsToLogAnalytics || sendLogsToStorageAccount)) { + location: location + name: '${(isNewWorkspace ? workSpaceName : 'placeholder')}/Microsoft.Insights/diagnosticSetting' + properties: { + storageAccountId: (sendLogsToStorageAccount ? storageAccountIdProperty : null) + eventHubAuthorizationRuleId: (sendLogsToEventHub ? hostpoolDiagnosticSettingsEventHubAuthorizationId : null) + eventHubName: (sendLogsToEventHub ? hostpoolDiagnosticSettingsEventHubName : null) + workspaceId: (sendLogsToLogAnalytics ? hostpoolDiagnosticSettingsLogAnalyticsWorkspaceId : null) + logs: workspaceDiagnosticSettingsLogProperties + } + dependsOn: [ + Workspace_linkedTemplate_deploymentId + ] +} + +output rdshVmNamesObject object = rdshVmNamesOutput diff --git a/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep b/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep new file mode 100644 index 000000000..f74a01aca --- /dev/null +++ b/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep @@ -0,0 +1,350 @@ +@description('The base URI where artifacts required by this template are located.') +param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' + +@description('The availability option for the VMs.') +@allowed([ + 'None' + 'AvailabilitySet' + 'AvailabilityZone' +]) +param availabilityOption string = 'None' + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string = '' + +@description('The number of availability zone to be used when create the VMs.') +@allowed([ + 1 + 2 + 3 +]) +param availabilityZone int = 1 + +@description('URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') +param vmImageVhdUri string + +@description('The storage account containing the custom VHD.') +param storageAccountResourceGroupName string + +@description('(Required when vmImageType = Gallery) Gallery image Offer.') +param vmGalleryImageOffer string = '' + +@description('(Required when vmImageType = Gallery) Gallery image Publisher.') +param vmGalleryImagePublisher string = '' + +@description('Whether the VM image has a plan or not') +param vmGalleryImageHasPlan bool = false + +@description('(Required when vmImageType = Gallery) Gallery image SKU.') +param vmGalleryImageSKU string = '' + +@description('(Required when vmImageType = Gallery) Gallery image version.') +param vmGalleryImageVersion string = '' + +@description('This prefix will be used in combination with the VM number to create the VM name. This value includes the dash, so if using “rdsh” as the prefix, VMs would be named “rdsh-0”, “rdsh-1”, etc. You should use a unique prefix to reduce name collisions in Active Directory.') +param rdshPrefix string = take(toLower(resourceGroup().name), 10) + +@description('Number of session hosts that will be created and added to the hostpool.') +param rdshNumberOfInstances int + +@description('The VM disk type for the VM: HDD or SSD.') +@allowed([ + 'Premium_LRS' + 'StandardSSD_LRS' + 'Standard_LRS' +]) +param rdshVMDiskType string + +@description('The size of the session host VMs.') +param rdshVmSize string = 'Standard_A2' + +@description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') +param enableAcceleratedNetworking bool = false + +@description('The username for the domain admin.') +param administratorAccountUsername string + +@description('The password that corresponds to the existing domain username.') +@secure() +param administratorAccountPassword string + +@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +param vmAdministratorAccountUsername string = '' + +@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +@secure() +param vmAdministratorAccountPassword string = '' + +@description('The URL to store unmanaged disks.') +param vhds string + +@description('The unique id of the subnet for the nics.') +param subnet_id string + +@description('Resource ID of the image.') +param rdshImageSourceId string = '' + +@description('Location for all resources to be created in.') +param location string = '' + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool = false + +@description('The resource id of an existing network security group') +param networkSecurityGroupId string = '' + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array = [] + +@description('The tags to be assigned to the network interfaces') +param networkInterfaceTags object = { +} + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object = { +} + +@description('The tags to be assigned to the virtual machines') +param virtualMachineTags object = { +} + +@description('The tags to be assigned to the images') +param imageTags object = { +} + +@description('VM name prefix initial number.') +param vmInitialNumber int = 0 +param guidValue string = newGuid() + +@description('The token for adding VMs to the hostpool') +param hostpoolToken string + +@description('The name of the hostpool') +param hostpoolName string + +@description('OUPath for the domain join') +param ouPath string = '' + +@description('Domain to join') +param domain string = '' + +@description('True if AAD Join, false if AD join') +param aadJoin bool = false + +@description('True if intune enrollment is selected. False otherwise') +param intune bool = false + +@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') +param bootDiagnostics object = { + enabled: false +} + +@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') +param userAssignedIdentity string = '' + +@description('ARM template that contains custom configurations to be run after the virtual machines are created.') +param customConfigurationTemplateUrl string = '../' + +@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') +param customConfigurationParameterUrl string = '../' + +@description('Session host configuration version of the host pool.') +param SessionHostConfigurationVersion string = '' + +var emptyArray = [] +var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) +var storageAccountType = rdshVMDiskType +var newNsgName = '${rdshPrefix}nsg-${guidValue}' +var newNsgDeploymentName_var = 'NSG-linkedTemplate-${guidValue}' +var nsgId = (createNetworkSecurityGroup ? resourceId('Microsoft.Network/networkSecurityGroups', newNsgName) : networkSecurityGroupId) +var isVMAdminAccountCredentialsProvided = ((vmAdministratorAccountUsername != '') && (vmAdministratorAccountPassword != '')) +var vmAdministratorUsername = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountUsername : first(split(administratorAccountUsername, '@'))) +var vmAdministratorPassword = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountPassword : administratorAccountPassword) +var vmAvailabilitySetResourceId = { + id: resourceId('Microsoft.Compute/availabilitySets/', availabilitySetName) +} +var planInfoEmpty = (empty(vmGalleryImageSKU) || empty(vmGalleryImagePublisher) || empty(vmGalleryImageOffer)) +var marketplacePlan = { + name: vmGalleryImageSKU + publisher: vmGalleryImagePublisher + product: vmGalleryImageOffer + version: (empty(vmGalleryImageVersion) ? 'latest' : vmGalleryImageVersion) +} +var vmPlan = ((planInfoEmpty || (!vmGalleryImageHasPlan)) ? json('null') : marketplacePlan) +var vmIdentityType = (aadJoin ? ((!empty(userAssignedIdentity)) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : ((!empty(userAssignedIdentity)) ? 'UserAssigned' : 'None')) +var vmIdentityTypeProperty = { + type: vmIdentityType +} +var vmUserAssignedIdentityProperty = { + userAssignedIdentities: { + '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', userAssignedIdentity)}': { + } + } +} +var vmIdentity = ((!empty(userAssignedIdentity)) ? union(vmIdentityTypeProperty, vmUserAssignedIdentityProperty) : vmIdentityTypeProperty) +var postDeploymentCustomConfigurationTemplateProperty = { + mode: 'Incremental' + templateLink: { + uri: customConfigurationTemplateUrl + contentVersion: '1.0.0.0' + } +} +var postDeploymentCustomConfigurationParameterProperty = { + parametersLink: { + uri: customConfigurationParameterUrl + } +} +var customConfigurationParameter = (empty(customConfigurationParameterUrl) ? postDeploymentCustomConfigurationTemplateProperty : union(postDeploymentCustomConfigurationTemplateProperty, postDeploymentCustomConfigurationParameterProperty)) + +module newNsgDeploymentName './nested_newNsgDeploymentName.bicep' = { + name: newNsgDeploymentName_var + params: { + variables_newNsgName: newNsgName + createNetworkSecurityGroup: createNetworkSecurityGroup + location: location + networkSecurityGroupTags: networkSecurityGroupTags + networkSecurityGroupRules: networkSecurityGroupRules + } +} + +resource rdshPrefix_vmInitialNumber_nic 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}-nic' + location: location + tags: networkInterfaceTags + properties: { + ipConfigurations: [ + { + name: 'ipconfig' + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: subnet_id + } + } + } + ] + enableAcceleratedNetworking: enableAcceleratedNetworking + networkSecurityGroup: (empty(networkSecurityGroupId) ? json('null') : json('{"id": "${nsgId}"}')) + } + dependsOn: [ + newNsgDeploymentName + ] +}] + +resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, rdshNumberOfInstances): { + name: concat(rdshPrefix, (i + vmInitialNumber)) + location: location + tags: virtualMachineTags + plan: vmPlan + identity: vmIdentity + properties: { + hardwareProfile: { + vmSize: rdshVmSize + } + availabilitySet: ((availabilityOption == 'AvailabilitySet') ? vmAvailabilitySetResourceId : json('null')) + osProfile: { + computerName: concat(rdshPrefix, (i + vmInitialNumber)) + adminUsername: vmAdministratorUsername + adminPassword: vmAdministratorPassword + } + storageProfile: { + osDisk: { + createOption: 'FromImage' + managedDisk: { + storageAccountType: storageAccountType + } + } + imageReference: { + id: rdshImageSourceId + } + } + networkProfile: { + networkInterfaces: [ + { + id: resourceId('Microsoft.Network/networkInterfaces', '${rdshPrefix}${(i + vmInitialNumber)}-nic') + } + ] + } + diagnosticsProfile: { + bootDiagnostics: bootDiagnostics + } + licenseType: 'Windows_Client' + } + zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) +}] + +resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}/Microsoft.PowerShell.DSC' + location: location + properties: { + publisher: 'Microsoft.Powershell' + type: 'DSC' + typeHandlerVersion: '2.73' + autoUpgradeMinorVersion: true + settings: { + modulesUrl: artifactsLocation + configurationFunction: 'Configuration.ps1\\AddSessionHost' + properties: { + hostPoolName: hostpoolName + registrationInfoToken: hostpoolToken + aadJoin: aadJoin + sessionHostConfigurationLastUpdateTime: SessionHostConfigurationVersion + } + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber + ] +}] + +resource rdshPrefix_vmInitialNumber_AADLoginForWindows 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/AADLoginForWindows' + location: location + properties: { + publisher: 'Microsoft.Azure.ActiveDirectory' + type: 'AADLoginForWindows' + typeHandlerVersion: '1.0' + autoUpgradeMinorVersion: true + settings: (intune ? { + mdmId: '0000000a-0000-0000-c000-000000000000' + } : json('null')) + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (!aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/joindomain' + location: location + properties: { + publisher: 'Microsoft.Compute' + type: 'JsonADDomainExtension' + typeHandlerVersion: '1.3' + autoUpgradeMinorVersion: true + settings: { + name: domain_var + ouPath: ouPath + user: administratorAccountUsername + restart: 'true' + options: '3' + } + protectedSettings: { + password: administratorAccountPassword + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +/*module post_deployment_custom_configurations '?' TODO: replace with correct path to post_deployment custom configs = if (!empty(customConfigurationTemplateUrl)) { + name: 'post-deployment-custom-configurations' + params: { + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + rdshPrefix_vmInitialNumber_AADLoginForWindows + rdshPrefix_vmInitialNumber_joindomain + ] +} */ diff --git a/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep b/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep new file mode 100644 index 000000000..a00782110 --- /dev/null +++ b/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep @@ -0,0 +1,366 @@ +@description('The base URI where artifacts required by this template are located.') +param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' + +@description('The availability option for the VMs.') +@allowed([ + 'None' + 'AvailabilitySet' + 'AvailabilityZone' +]) +param availabilityOption string = 'None' + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string = '' + +@description('The number of availability zone to be used when create the VMs.') +@allowed([ + 1 + 2 + 3 +]) +param availabilityZone int = 1 + +@description('URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') +param vmImageVhdUri string + +@description('The storage account containing the custom VHD.') +param storageAccountResourceGroupName string + +@description('(Required when vmImageType = Gallery) Gallery image Offer.') +param vmGalleryImageOffer string = '' + +@description('(Required when vmImageType = Gallery) Gallery image Publisher.') +param vmGalleryImagePublisher string = '' + +@description('Whether the VM image has a plan or not') +param vmGalleryImageHasPlan bool = false + +@description('(Required when vmImageType = Gallery) Gallery image SKU.') +param vmGalleryImageSKU string = '' + +@description('(Required when vmImageType = Gallery) Gallery image version.') +param vmGalleryImageVersion string = '' + +@description('This prefix will be used in combination with the VM number to create the VM name. This value includes the dash, so if using “rdsh” as the prefix, VMs would be named “rdsh-0”, “rdsh-1”, etc. You should use a unique prefix to reduce name collisions in Active Directory.') +param rdshPrefix string = take(toLower(resourceGroup().name), 10) + +@description('Number of session hosts that will be created and added to the hostpool.') +param rdshNumberOfInstances int + +@description('The VM disk type for the VM: HDD or SSD.') +@allowed([ + 'Premium_LRS' + 'StandardSSD_LRS' + 'Standard_LRS' +]) +param rdshVMDiskType string + +@description('The size of the session host VMs.') +param rdshVmSize string = 'Standard_A2' + +@description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') +param enableAcceleratedNetworking bool = false + +@description('The username for the domain admin.') +param administratorAccountUsername string + +@description('The password that corresponds to the existing domain username.') +@secure() +param administratorAccountPassword string + +@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +param vmAdministratorAccountUsername string = '' + +@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +@secure() +param vmAdministratorAccountPassword string = '' + +@description('The URL to store unmanaged disks.') +param vhds string + +@description('The unique id of the subnet for the nics.') +param subnet_id string + +@description('Resource ID of the image.') +param rdshImageSourceId string = '' + +@description('Location for all resources to be created in.') +param location string = '' + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool = false + +@description('The resource id of an existing network security group') +param networkSecurityGroupId string = '' + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array = [] + +@description('The tags to be assigned to the network interfaces') +param networkInterfaceTags object = { +} + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object = { +} + +@description('The tags to be assigned to the virtual machines') +param virtualMachineTags object = { +} + +@description('The tags to be assigned to the images') +param imageTags object = { +} + +@description('VM name prefix initial number.') +param vmInitialNumber int = 0 +param guidValue string = newGuid() + +@description('The token for adding VMs to the hostpool') +param hostpoolToken string + +@description('The name of the hostpool') +param hostpoolName string + +@description('OUPath for the domain join') +param ouPath string = '' + +@description('Domain to join') +param domain string = '' + +@description('True if AAD Join, false if AD join') +param aadJoin bool = false + +@description('True if intune enrollment is selected. False otherwise') +param intune bool = false + +@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') +param bootDiagnostics object = { + enabled: false +} + +@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') +param userAssignedIdentity string = '' + +@description('ARM template that contains custom configurations to be run after the virtual machines are created.') +param customConfigurationTemplateUrl string = '' + +@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') +param customConfigurationParameterUrl string = '' + +@description('Session host configuration version of the host pool.') +param SessionHostConfigurationVersion string = '' + +var emptyArray = [] +var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) +var storageAccountType = rdshVMDiskType +var imageName_var = '${rdshPrefix}image' +var newNsgName = '${rdshPrefix}nsg-${guidValue}' +var newNsgDeploymentName_var = 'NSG-linkedTemplate-${guidValue}' +var nsgId = (createNetworkSecurityGroup ? resourceId('Microsoft.Network/networkSecurityGroups', newNsgName) : networkSecurityGroupId) +var isVMAdminAccountCredentialsProvided = ((vmAdministratorAccountUsername != '') && (vmAdministratorAccountPassword != '')) +var vmAdministratorUsername = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountUsername : first(split(administratorAccountUsername, '@'))) +var vmAdministratorPassword = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountPassword : administratorAccountPassword) +var vmAvailabilitySetResourceId = { + id: resourceId('Microsoft.Compute/availabilitySets/', availabilitySetName) +} +var planInfoEmpty = (empty(vmGalleryImageSKU) || empty(vmGalleryImagePublisher) || empty(vmGalleryImageOffer)) +var marketplacePlan = { + name: vmGalleryImageSKU + publisher: vmGalleryImagePublisher + product: vmGalleryImageOffer +} +var vmPlan = ((planInfoEmpty || (!vmGalleryImageHasPlan)) ? json('null') : marketplacePlan) +var vmIdentityType = (aadJoin ? ((!empty(userAssignedIdentity)) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : ((!empty(userAssignedIdentity)) ? 'UserAssigned' : 'None')) +var vmIdentityTypeProperty = { + type: vmIdentityType +} +var vmUserAssignedIdentityProperty = { + userAssignedIdentities: { + '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', userAssignedIdentity)}': { + } + } +} +var vmIdentity = ((!empty(userAssignedIdentity)) ? union(vmIdentityTypeProperty, vmUserAssignedIdentityProperty) : vmIdentityTypeProperty) +var postDeploymentCustomConfigurationTemplateProperty = { + mode: 'Incremental' + templateLink: { + uri: customConfigurationTemplateUrl + contentVersion: '1.0.0.0' + } +} +var postDeploymentCustomConfigurationParameterProperty = { + parametersLink: { + uri: customConfigurationParameterUrl + } +} +var customConfigurationParameter = (empty(customConfigurationParameterUrl) ? postDeploymentCustomConfigurationTemplateProperty : union(postDeploymentCustomConfigurationTemplateProperty, postDeploymentCustomConfigurationParameterProperty)) + +resource imageName 'Microsoft.Compute/images@2018-10-01' = { + name: imageName_var + location: location + tags: imageTags + properties: { + storageProfile: { + osDisk: { + osType: 'Windows' + osState: 'Generalized' + blobUri: vmImageVhdUri + storageAccountType: storageAccountType + } + } + } +} + +module newNsgDeploymentName './nested_newNsgDeploymentName.bicep' = { + name: newNsgDeploymentName_var + params: { + variables_newNsgName: newNsgName + createNetworkSecurityGroup: createNetworkSecurityGroup + location: location + networkSecurityGroupTags: networkSecurityGroupTags + networkSecurityGroupRules: networkSecurityGroupRules + } +} + +resource rdshPrefix_vmInitialNumber_nic 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}-nic' + location: location + tags: networkInterfaceTags + properties: { + ipConfigurations: [ + { + name: 'ipconfig' + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: subnet_id + } + } + } + ] + enableAcceleratedNetworking: enableAcceleratedNetworking + networkSecurityGroup: (empty(networkSecurityGroupId) ? json('null') : json('{"id": "${nsgId}"}')) + } + dependsOn: [ + newNsgDeploymentName + ] +}] + +resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, rdshNumberOfInstances): { + name: concat(rdshPrefix, (i + vmInitialNumber)) + location: location + tags: virtualMachineTags + plan: vmPlan + identity: vmIdentity + properties: { + hardwareProfile: { + vmSize: rdshVmSize + } + availabilitySet: ((availabilityOption == 'AvailabilitySet') ? vmAvailabilitySetResourceId : json('null')) + osProfile: { + computerName: concat(rdshPrefix, (i + vmInitialNumber)) + adminUsername: vmAdministratorUsername + adminPassword: vmAdministratorPassword + } + storageProfile: { + osDisk: { + createOption: 'FromImage' + managedDisk: { + storageAccountType: storageAccountType + } + } + imageReference: { + id: imageName.id + } + } + networkProfile: { + networkInterfaces: [ + { + id: resourceId('Microsoft.Network/networkInterfaces', '${rdshPrefix}${(i + vmInitialNumber)}-nic') + } + ] + } + diagnosticsProfile: { + bootDiagnostics: bootDiagnostics + } + licenseType: 'Windows_Client' + } + zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) +}] + +resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}/Microsoft.PowerShell.DSC' + location: location + properties: { + publisher: 'Microsoft.Powershell' + type: 'DSC' + typeHandlerVersion: '2.73' + autoUpgradeMinorVersion: true + settings: { + modulesUrl: artifactsLocation + configurationFunction: 'Configuration.ps1\\AddSessionHost' + properties: { + hostPoolName: hostpoolName + registrationInfoToken: hostpoolToken + aadJoin: aadJoin + sessionHostConfigurationLastUpdateTime: SessionHostConfigurationVersion + } + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber + ] +}] + +resource rdshPrefix_vmInitialNumber_AADLoginForWindows 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/AADLoginForWindows' + location: location + properties: { + publisher: 'Microsoft.Azure.ActiveDirectory' + type: 'AADLoginForWindows' + typeHandlerVersion: '1.0' + autoUpgradeMinorVersion: true + settings: (intune ? { + mdmId: '0000000a-0000-0000-c000-000000000000' + } : json('null')) + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (!aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/joindomain' + location: location + properties: { + publisher: 'Microsoft.Compute' + type: 'JsonADDomainExtension' + typeHandlerVersion: '1.3' + autoUpgradeMinorVersion: true + settings: { + name: domain_var + ouPath: ouPath + user: administratorAccountUsername + restart: 'true' + options: '3' + } + protectedSettings: { + password: administratorAccountPassword + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +/*module post_deployment_custom_configuration '?' TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { + name: 'post-deployment-custom-configuration' + params: { + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + rdshPrefix_vmInitialNumber_AADLoginForWindows + rdshPrefix_vmInitialNumber_joindomain + ] +}*/ diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep new file mode 100644 index 000000000..928b87d54 --- /dev/null +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -0,0 +1,355 @@ +@description('The base URI where artifacts required by this template are located.') +param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' + +@description('The availability option for the VMs.') +@allowed([ + 'None' + 'AvailabilitySet' + 'AvailabilityZone' +]) +param availabilityOption string = 'None' + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string = '' + +@description('The number of availability zone to be used when create the VMs.') +@allowed([ + 1 + 2 + 3 +]) +param availabilityZone int = 1 + +@description('URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') +param vmImageVhdUri string + +@description('The storage account containing the custom VHD.') +param storageAccountResourceGroupName string + +@description('(Required when vmImageType = Gallery) Gallery image Offer.') +param vmGalleryImageOffer string = '' + +@description('(Required when vmImageType = Gallery) Gallery image Publisher.') +param vmGalleryImagePublisher string = '' + +@description('Whether the VM image has a plan or not') +param vmGalleryImageHasPlan bool = false + +@description('(Required when vmImageType = Gallery) Gallery image SKU.') +param vmGalleryImageSKU string = '' + +@description('(Required when vmImageType = Gallery) Gallery image version.') +param vmGalleryImageVersion string = '' + +@description('This prefix will be used in combination with the VM number to create the VM name. This value includes the dash, so if using “rdsh” as the prefix, VMs would be named “rdsh-0”, “rdsh-1”, etc. You should use a unique prefix to reduce name collisions in Active Directory.') +param rdshPrefix string = take(toLower(resourceGroup().name), 10) + +@description('Number of session hosts that will be created and added to the hostpool.') +param rdshNumberOfInstances int + +@description('The VM disk type for the VM: HDD or SSD.') +@allowed([ + 'Premium_LRS' + 'StandardSSD_LRS' + 'Standard_LRS' +]) +param rdshVMDiskType string + +@description('The size of the session host VMs.') +param rdshVmSize string = 'Standard_A2' + +@description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') +param enableAcceleratedNetworking bool = false + +@description('The username for the domain admin.') +param administratorAccountUsername string + +@description('The password that corresponds to the existing domain username.') +@secure() +param administratorAccountPassword string + +@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +param vmAdministratorAccountUsername string = '' + +@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +@secure() +param vmAdministratorAccountPassword string = '' + +@description('The URL to store unmanaged disks.') +param vhds string + +@description('The unique id of the subnet for the nics.') +param subnet_id string + +@description('Resource ID of the image.') +param rdshImageSourceId string = '' + +@description('Location for all resources to be created in.') +param location string = '' + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool = false + +@description('The resource id of an existing network security group') +param networkSecurityGroupId string = '' + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array = [] + +@description('The tags to be assigned to the network interfaces') +param networkInterfaceTags object = { +} + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object = { +} + +@description('The tags to be assigned to the virtual machines') +param virtualMachineTags object = { +} + +@description('The tags to be assigned to the images') +param imageTags object = { +} + +@description('VM name prefix initial number.') +param vmInitialNumber int = 0 +param guidValue string = newGuid() + +@description('The token for adding VMs to the hostpool') +param hostpoolToken string + +@description('The name of the hostpool') +param hostpoolName string + +@description('OUPath for the domain join') +param ouPath string = '' + +@description('Domain to join') +param domain string = '' + +@description('True if AAD Join, false if AD join') +param aadJoin bool = false + +@description('True if intune enrollment is selected. False otherwise') +param intune bool = false + +@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') +param bootDiagnostics object = { + enabled: false +} + +@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') +param userAssignedIdentity string = '' + +@description('ARM template that contains custom configurations to be run after the virtual machines are created.') +param customConfigurationTemplateUrl string = '' + +@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') +param customConfigurationParameterUrl string = '' + +@description('Session host configuration version of the host pool.') +param SessionHostConfigurationVersion string = '' + +var emptyArray = [] +var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) +var storageAccountType = rdshVMDiskType +var newNsgName = '${rdshPrefix}nsg-${guidValue}' +var newNsgDeploymentName_var = 'NSG-linkedTemplate-${guidValue}' +var nsgId = (createNetworkSecurityGroup ? resourceId('Microsoft.Network/networkSecurityGroups', newNsgName) : networkSecurityGroupId) +var isVMAdminAccountCredentialsProvided = ((vmAdministratorAccountUsername != '') && (vmAdministratorAccountPassword != '')) +var vmAdministratorUsername = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountUsername : first(split(administratorAccountUsername, '@'))) +var vmAdministratorPassword = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountPassword : administratorAccountPassword) +var vmAvailabilitySetResourceId = { + id: resourceId('Microsoft.Compute/availabilitySets/', availabilitySetName) +} +var planInfoEmpty = (empty(vmGalleryImageSKU) || empty(vmGalleryImagePublisher) || empty(vmGalleryImageOffer)) +var marketplacePlan = { + name: vmGalleryImageSKU + publisher: vmGalleryImagePublisher + product: vmGalleryImageOffer +} +var vmPlan = ((planInfoEmpty || (!vmGalleryImageHasPlan)) ? json('null') : marketplacePlan) +var vmIdentityType = (aadJoin ? ((!empty(userAssignedIdentity)) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : ((!empty(userAssignedIdentity)) ? 'UserAssigned' : 'None')) +var vmIdentityTypeProperty = { + type: vmIdentityType +} +var vmUserAssignedIdentityProperty = { + userAssignedIdentities: { + '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', userAssignedIdentity)}': { + } + } +} +var vmIdentity = ((!empty(userAssignedIdentity)) ? union(vmIdentityTypeProperty, vmUserAssignedIdentityProperty) : vmIdentityTypeProperty) +var postDeploymentCustomConfigurationTemplateProperty = { + mode: 'Incremental' + templateLink: { + uri: customConfigurationTemplateUrl + contentVersion: '1.0.0.0' + } +} +var postDeploymentCustomConfigurationParameterProperty = { + parametersLink: { + uri: customConfigurationParameterUrl + } +} +var customConfigurationParameter = (empty(customConfigurationParameterUrl) ? postDeploymentCustomConfigurationTemplateProperty : union(postDeploymentCustomConfigurationTemplateProperty, postDeploymentCustomConfigurationParameterProperty)) + +module newNsgDeploymentName './nested_newNsgDeploymentName.bicep' = { + name: newNsgDeploymentName_var + params: { + variables_newNsgName: newNsgName + createNetworkSecurityGroup: createNetworkSecurityGroup + location: location + networkSecurityGroupTags: networkSecurityGroupTags + networkSecurityGroupRules: networkSecurityGroupRules + } +} + +resource rdshPrefix_vmInitialNumber_nic 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}-nic' + location: location + tags: networkInterfaceTags + properties: { + ipConfigurations: [ + { + name: 'ipconfig' + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: subnet_id + } + } + } + ] + enableAcceleratedNetworking: enableAcceleratedNetworking + networkSecurityGroup: (empty(networkSecurityGroupId) ? json('null') : json('{"id": "${nsgId}"}')) + } + dependsOn: [ + newNsgDeploymentName + ] +}] + +resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, rdshNumberOfInstances): { + name: concat(rdshPrefix, (i + vmInitialNumber)) + location: location + tags: virtualMachineTags + plan: vmPlan + identity: vmIdentity + properties: { + hardwareProfile: { + vmSize: rdshVmSize + } + availabilitySet: ((availabilityOption == 'AvailabilitySet') ? vmAvailabilitySetResourceId : json('null')) + osProfile: { + computerName: concat(rdshPrefix, (i + vmInitialNumber)) + adminUsername: vmAdministratorUsername + adminPassword: vmAdministratorPassword + } + storageProfile: { + imageReference: { + publisher: vmGalleryImagePublisher + offer: vmGalleryImageOffer + sku: vmGalleryImageSKU + version: (empty(vmGalleryImageVersion) ? 'latest' : vmGalleryImageVersion) + } + osDisk: { + createOption: 'FromImage' + managedDisk: { + storageAccountType: storageAccountType + } + } + } + networkProfile: { + networkInterfaces: [ + { + id: resourceId('Microsoft.Network/networkInterfaces', '${rdshPrefix}${(i + vmInitialNumber)}-nic') + } + ] + } + diagnosticsProfile: { + bootDiagnostics: bootDiagnostics + } + licenseType: 'Windows_Client' + } + zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) + dependsOn: [ + 'Microsoft.Network/networkInterfaces/${rdshPrefix}${(i + vmInitialNumber)}-nic' + ] +}] + +resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}/Microsoft.PowerShell.DSC' + location: location + properties: { + publisher: 'Microsoft.Powershell' + type: 'DSC' + typeHandlerVersion: '2.73' + autoUpgradeMinorVersion: true + settings: { + modulesUrl: artifactsLocation + configurationFunction: 'Configuration.ps1\\AddSessionHost' + properties: { + hostPoolName: hostpoolName + registrationInfoToken: hostpoolToken + aadJoin: aadJoin + sessionHostConfigurationLastUpdateTime: SessionHostConfigurationVersion + } + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber + ] +}] + +resource rdshPrefix_vmInitialNumber_AADLoginForWindows 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/AADLoginForWindows' + location: location + properties: { + publisher: 'Microsoft.Azure.ActiveDirectory' + type: 'AADLoginForWindows' + typeHandlerVersion: '1.0' + autoUpgradeMinorVersion: true + settings: (intune ? { + mdmId: '0000000a-0000-0000-c000-000000000000' + } : json('null')) + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (!aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/joindomain' + location: location + properties: { + publisher: 'Microsoft.Compute' + type: 'JsonADDomainExtension' + typeHandlerVersion: '1.3' + autoUpgradeMinorVersion: true + settings: { + name: domain_var + ouPath: ouPath + user: administratorAccountUsername + restart: 'true' + options: '3' + } + protectedSettings: { + password: administratorAccountPassword + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be*/ = if (!empty(customConfigurationTemplateUrl)) { + name: 'post-deployment-custom-configuration' + params: { + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + rdshPrefix_vmInitialNumber_AADLoginForWindows + rdshPrefix_vmInitialNumber_joindomain + ] +} \ No newline at end of file diff --git a/bicep-templates/nestedtemplates/nested_AVSet_linkedTemplate_deploymentId.bicep b/bicep-templates/nestedtemplates/nested_AVSet_linkedTemplate_deploymentId.bicep new file mode 100644 index 000000000..830794462 --- /dev/null +++ b/bicep-templates/nestedtemplates/nested_AVSet_linkedTemplate_deploymentId.bicep @@ -0,0 +1,56 @@ +param avSetSKU string + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string + +@description('The location of the session host VMs.') +param vmLocation string + +@description('The tags to be assigned to the availability set') +param availabilitySetTags object + +@description('The platform update domain count of avaiability set to be created.') +@allowed([ + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 +]) +param availabilitySetUpdateDomainCount int + +@description('The platform fault domain count of avaiability set to be created.') +@allowed([ + 1 + 2 + 3 +]) +param availabilitySetFaultDomainCount int + +resource availabilitySetName_resource 'Microsoft.Compute/availabilitySets@2018-10-01' = { + name: availabilitySetName + location: vmLocation + tags: availabilitySetTags + properties: { + platformUpdateDomainCount: availabilitySetUpdateDomainCount + platformFaultDomainCount: availabilitySetFaultDomainCount + } + sku: { + name: avSetSKU + } +} diff --git a/bicep-templates/nestedtemplates/nested_NSG_linkedTemplate.bicep b/bicep-templates/nestedtemplates/nested_NSG_linkedTemplate.bicep new file mode 100644 index 000000000..5c87ba3a6 --- /dev/null +++ b/bicep-templates/nestedtemplates/nested_NSG_linkedTemplate.bicep @@ -0,0 +1,14 @@ +param createNetworkSecurityGroup bool +param newNsgName string +param location string +param networkSecurityGroupTags object +param networkSecurityGroupRules array + +resource newNsgName_resource 'Microsoft.Network/networkSecurityGroups@2019-02-01' = if (createNetworkSecurityGroup) { + name: newNsgName + location: location + tags: networkSecurityGroupTags + properties: { + securityRules: networkSecurityGroupRules + } +} \ No newline at end of file diff --git a/bicep-templates/nestedtemplates/nested_UpdateHostPool_deploymentId.bicep b/bicep-templates/nestedtemplates/nested_UpdateHostPool_deploymentId.bicep new file mode 100644 index 000000000..ad2fa9cde --- /dev/null +++ b/bicep-templates/nestedtemplates/nested_UpdateHostPool_deploymentId.bicep @@ -0,0 +1,14 @@ +@description('The name of the Hostpool to be created.') +param hostpoolName string + +@description('The location of the host pool to be updated. Used when the host pool was created empty.') +param hostpoolLocation string + +@description('The properties of the Hostpool to be updated. Used when the host pool was created empty.') +param hostpoolProperties object + +resource hostpoolName_resource 'Microsoft.DesktopVirtualization/hostpools@2019-12-10-preview' = { + name: hostpoolName + location: hostpoolLocation + properties: hostpoolProperties +} diff --git a/bicep-templates/nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep b/bicep-templates/nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep new file mode 100644 index 000000000..6e0a14e38 --- /dev/null +++ b/bicep-templates/nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep @@ -0,0 +1,12 @@ +//param apiVersion string +param workSpaceName string +param workspaceLocation string +param applicationGroupReferencesArr array + +resource workSpaceName_resource 'Microsoft.DesktopVirtualization/workspaces@2019-12-10-preview' = { + name: workSpaceName + location: workspaceLocation + properties: { + applicationGroupReferences: applicationGroupReferencesArr + } +} diff --git a/bicep-templates/nestedtemplates/nested_newNsgDeploymentName.bicep b/bicep-templates/nestedtemplates/nested_newNsgDeploymentName.bicep new file mode 100644 index 000000000..8407fbbcc --- /dev/null +++ b/bicep-templates/nestedtemplates/nested_newNsgDeploymentName.bicep @@ -0,0 +1,22 @@ +param variables_newNsgName string /* TODO: fill in correct type */ + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool + +@description('Location for all resources to be created in.') +param location string + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array + +resource variables_newNsgName_resource 'Microsoft.Network/networkSecurityGroups@2019-02-01' = if (createNetworkSecurityGroup) { + name: variables_newNsgName + location: location + tags: networkSecurityGroupTags + properties: { + securityRules: networkSecurityGroupRules + } +} diff --git a/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep b/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep new file mode 100644 index 000000000..642695789 --- /dev/null +++ b/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep @@ -0,0 +1,345 @@ +@description('The base URI where artifacts required by this template are located.') +param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' + +@description('The availability option for the VMs.') +@allowed([ + 'None' + 'AvailabilitySet' + 'AvailabilityZone' +]) +param availabilityOption string = 'None' + +@description('The name of avaiability set to be used when create the VMs.') +param availabilitySetName string = '' + +@description('The number of availability zone to be used when create the VMs.') +@allowed([ + 1 + 2 + 3 +]) +param availabilityZone int = 1 + +@description('URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') +param vmImageVhdUri string + +@description('The storage account containing the custom VHD.') +param storageAccountResourceGroupName string + +@description('(Required when vmImageType = Gallery) Gallery image Offer.') +param vmGalleryImageOffer string = '' + +@description('(Required when vmImageType = Gallery) Gallery image Publisher.') +param vmGalleryImagePublisher string = '' + +@description('Whether the VM image has a plan or not') +param vmGalleryImageHasPlan bool = false + +@description('(Required when vmImageType = Gallery) Gallery image SKU.') +param vmGalleryImageSKU string = '' + +@description('(Required when vmImageType = Gallery) Gallery image version.') +param vmGalleryImageVersion string = '' + +@description('This prefix will be used in combination with the VM number to create the VM name. This value includes the dash, so if using “rdsh” as the prefix, VMs would be named “rdsh-0”, “rdsh-1”, etc. You should use a unique prefix to reduce name collisions in Active Directory.') +param rdshPrefix string = take(toLower(resourceGroup().name), 10) + +@description('Number of session hosts that will be created and added to the hostpool.') +param rdshNumberOfInstances int + +@description('The VM disk type for the VM: HDD or SSD.') +@allowed([ + 'Premium_LRS' + 'StandardSSD_LRS' + 'Standard_LRS' +]) +param rdshVMDiskType string + +@description('The size of the session host VMs.') +param rdshVmSize string = 'Standard_A2' + +@description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') +param enableAcceleratedNetworking bool = false + +@description('The username for the domain admin.') +param administratorAccountUsername string + +@description('The password that corresponds to the existing domain username.') +@secure() +param administratorAccountPassword string + +@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +param vmAdministratorAccountUsername string = '' + +@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') +@secure() +param vmAdministratorAccountPassword string = '' + +@description('The URL to store unmanaged disks.') +param vhds string + +@description('The unique id of the subnet for the nics.') +param subnet_id string + +@description('Resource ID of the image.') +param rdshImageSourceId string = '' + +@description('Location for all resources to be created in.') +param location string = '' + +@description('Whether to create a new network security group or use an existing one') +param createNetworkSecurityGroup bool = false + +@description('The resource id of an existing network security group') +param networkSecurityGroupId string = '' + +@description('The rules to be given to the new network security group') +param networkSecurityGroupRules array = [] + +@description('The tags to be assigned to the network interfaces') +param networkInterfaceTags object = { +} + +@description('The tags to be assigned to the network security groups') +param networkSecurityGroupTags object = { +} + +@description('The tags to be assigned to the virtual machines') +param virtualMachineTags object = { +} + +@description('The tags to be assigned to the images') +param imageTags object = { +} + +@description('VM name prefix initial number.') +param vmInitialNumber int = 0 +param guidValue string = newGuid() + +@description('The token for adding VMs to the hostpool') +param hostpoolToken string + +@description('The name of the hostpool') +param hostpoolName string + +@description('OUPath for the domain join') +param ouPath string = '' + +@description('Domain to join') +param domain string = '' + +@description('True if AAD Join, false if AD join') +param aadJoin bool = false + +@description('True if intune enrollment is selected. False otherwise') +param intune bool = false + +@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') +param bootDiagnostics object = { + enabled: false +} + +@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') +param userAssignedIdentity string = '' + +@description('ARM template that contains custom configurations to be run after the virtual machines are created.') +param customConfigurationTemplateUrl string = '' + +@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') +param customConfigurationParameterUrl string = '' + +@description('Session host configuration version of the host pool.') +param SessionHostConfigurationVersion string = '' + +var emptyArray = [] +var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) +var storageAccountName = split(split(vmImageVhdUri, '/')[2], '.')[0] +var storageaccount = concat(resourceId(storageAccountResourceGroupName, 'Microsoft.Storage/storageAccounts', storageAccountName)) +var newNsgName = '${rdshPrefix}nsg-${guidValue}' +var newNsgDeploymentName_var = 'NSG-linkedTemplate-${guidValue}' +var nsgId = (createNetworkSecurityGroup ? resourceId('Microsoft.Network/networkSecurityGroups', newNsgName) : networkSecurityGroupId) +var isVMAdminAccountCredentialsProvided = ((vmAdministratorAccountUsername != '') && (vmAdministratorAccountPassword != '')) +var vmAdministratorUsername = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountUsername : first(split(administratorAccountUsername, '@'))) +var vmAdministratorPassword = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountPassword : administratorAccountPassword) +var vmAvailabilitySetResourceId = { + id: resourceId('Microsoft.Compute/availabilitySets/', availabilitySetName) +} +var vmIdentityType = (aadJoin ? ((!empty(userAssignedIdentity)) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : ((!empty(userAssignedIdentity)) ? 'UserAssigned' : 'None')) +var vmIdentityTypeProperty = { + type: vmIdentityType +} +var vmUserAssignedIdentityProperty = { + userAssignedIdentities: { + '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', userAssignedIdentity)}': { + } + } +} +var vmIdentity = ((!empty(userAssignedIdentity)) ? union(vmIdentityTypeProperty, vmUserAssignedIdentityProperty) : vmIdentityTypeProperty) +var postDeploymentCustomConfigurationTemplateProperty = { + mode: 'Incremental' + templateLink: { + uri: customConfigurationTemplateUrl + contentVersion: '1.0.0.0' + } +} +var postDeploymentCustomConfigurationParameterProperty = { + parametersLink: { + uri: customConfigurationParameterUrl + } +} +var customConfigurationParameter = (empty(customConfigurationParameterUrl) ? postDeploymentCustomConfigurationTemplateProperty : union(postDeploymentCustomConfigurationTemplateProperty, postDeploymentCustomConfigurationParameterProperty)) + +module newNsgDeploymentName './nested_newNsgDeploymentName.bicep' = { + name: newNsgDeploymentName_var + params: { + variables_newNsgName: newNsgName + createNetworkSecurityGroup: createNetworkSecurityGroup + location: location + networkSecurityGroupTags: networkSecurityGroupTags + networkSecurityGroupRules: networkSecurityGroupRules + } +} + +resource rdshPrefix_vmInitialNumber_nic 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}-nic' + location: location + tags: networkInterfaceTags + properties: { + ipConfigurations: [ + { + name: 'ipconfig' + properties: { + privateIPAllocationMethod: 'Dynamic' + subnet: { + id: subnet_id + } + } + } + ] + enableAcceleratedNetworking: enableAcceleratedNetworking + networkSecurityGroup: (empty(networkSecurityGroupId) ? json('null') : json('{"id": "${nsgId}"}')) + } + dependsOn: [ + newNsgDeploymentName + ] +}] + +resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, rdshNumberOfInstances): { + name: concat(rdshPrefix, (i + vmInitialNumber)) + location: location + tags: virtualMachineTags + identity: vmIdentity + properties: { + hardwareProfile: { + vmSize: rdshVmSize + } + availabilitySet: ((availabilityOption == 'AvailabilitySet') ? vmAvailabilitySetResourceId : json('null')) + osProfile: { + computerName: concat(rdshPrefix, (i + vmInitialNumber)) + adminUsername: vmAdministratorUsername + adminPassword: vmAdministratorPassword + } + storageProfile: { + osDisk: { + name: '${rdshPrefix}${(i + vmInitialNumber)}-osDisk' + osType: 'Windows' + caching: 'ReadWrite' + createOption: 'FromImage' + image: { + uri: vmImageVhdUri + } + vhd: { + uri: '${reference(storageaccount, '2018-11-01').primaryEndpoints.blob}${vhds}${(i + vmInitialNumber)}-osdisk.vhd' + } + } + } + networkProfile: { + networkInterfaces: [ + { + id: resourceId('Microsoft.Network/networkInterfaces', '${rdshPrefix}${(i + vmInitialNumber)}-nic') + } + ] + } + diagnosticsProfile: { + bootDiagnostics: bootDiagnostics + } + licenseType: 'Windows_Client' + } + zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) +}] + +resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { + name: '${rdshPrefix}${(i + vmInitialNumber)}/Microsoft.PowerShell.DSC' + location: location + properties: { + publisher: 'Microsoft.Powershell' + type: 'DSC' + typeHandlerVersion: '2.73' + autoUpgradeMinorVersion: true + settings: { + modulesUrl: artifactsLocation + configurationFunction: 'Configuration.ps1\\AddSessionHost' + properties: { + hostPoolName: hostpoolName + registrationInfoToken: hostpoolToken + aadJoin: aadJoin + sessionHostConfigurationLastUpdateTime: SessionHostConfigurationVersion + } + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber + ] +}] + +resource rdshPrefix_vmInitialNumber_AADLoginForWindows 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/AADLoginForWindows' + location: location + properties: { + publisher: 'Microsoft.Azure.ActiveDirectory' + type: 'AADLoginForWindows' + typeHandlerVersion: '1.0' + autoUpgradeMinorVersion: true + settings: (intune ? { + mdmId: '0000000a-0000-0000-c000-000000000000' + } : json('null')) + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (!aadJoin) { + name: '${rdshPrefix}${(i + vmInitialNumber)}/joindomain' + location: location + properties: { + publisher: 'Microsoft.Compute' + type: 'JsonADDomainExtension' + typeHandlerVersion: '1.3' + autoUpgradeMinorVersion: true + settings: { + name: domain_var + ouPath: ouPath + user: administratorAccountUsername + restart: 'true' + options: '3' + } + protectedSettings: { + password: administratorAccountPassword + } + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + ] +}] + +/*module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { + name: 'post-deployment-custom-configuration' + params: { + } + dependsOn: [ + rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC + rdshPrefix_vmInitialNumber_AADLoginForWindows + rdshPrefix_vmInitialNumber_joindomain + ] +}*/ From 543d0f3c48fe6bf419ce7e745a892981bff4b65b Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Mon, 27 Jun 2022 20:01:13 -0700 Subject: [PATCH 02/17] Tested VM creation with BICEP successfully --- .../AddVirtualMachinesTemplate.bicep | 120 +++++++++- .../CreateHostpoolTemplate.bicep | 220 +++++++++++++++++- .../managedDisks-customvhdvm.bicep | 2 +- .../managedDisks-galleryvm.bicep | 7 +- .../unmanagedDisks-customvhdvm.bicep | 3 +- 5 files changed, 323 insertions(+), 29 deletions(-) diff --git a/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep b/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep index 4d7e72b7a..cc4ba56d3 100644 --- a/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep +++ b/bicep-templates/AddVirtualMachinesToHostPool/AddVirtualMachinesTemplate.bicep @@ -143,12 +143,11 @@ param vmCustomImageSourceId string = '' @description('The VM disk type for the VM: HDD or SSD.') @allowed([ - 'UltraSSD_LRS' 'Premium_LRS' 'StandardSSD_LRS' 'Standard_LRS' ]) -param vmDiskType string +param vmDiskType string = 'Standard_LRS' @description('True indicating you would like to use managed disks or false indicating you would like to use unmanaged disks.') param vmUseManagedDisks bool @@ -234,7 +233,7 @@ var rdshManagedDisks = ((vmImageType == 'CustomVHD') ? vmUseManagedDisks : bool( var rdshPrefix = '${vmNamePrefix}-' var avSetSKU = (rdshManagedDisks ? 'Aligned' : 'Classic') var vhds = 'vhds/${rdshPrefix}' -var subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) +var var_subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) var vmTemplateName = '${(rdshManagedDisks ? 'managedDisks' : 'unmanagedDisks')}-${toLower(replace(vmImageType, ' ', ''))}vm' var vmTemplateUri = '${nestedTemplatesLocation}${vmTemplateName}.json' var rdshVmNamesCopyNamesArr = [for item in range(0, (vmNumberOfInstances)): { @@ -268,9 +267,9 @@ module AVSet_linkedTemplate_deploymentId '../nestedtemplates/nested_AVSet_linked UpdateHostPool_deploymentId ] } -/*TODO: replace with correct path to [variables('vmTemplateUri')] Bicep currently does not "support string interpolation in FilePaths." This is going to require some deeper refactoring, Either by using BICEP PUBLISH, or keeping local copy in the GitHub repo.*/ -module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json locally to my build and convert to bicep only for workaround, ask preference next meeting*/ = { - name: 'vmCreation-linkedTemplate-${deploymentId}' + +module vmCreation_managed_customvhdvm '../nestedtemplates/managedDisks-customvhdvm.bicep' = if (vmTemplateUri == 'managedDisks-customvhdvm.bicep') { + name: 'vmCreation_managed_customvhdvm-${deploymentId}' scope: resourceGroup(vmResourceGroup) params: { artifactsLocation: artifactsLocation @@ -293,7 +292,7 @@ module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json vmAdministratorAccountPassword: vmAdministratorAccountPassword administratorAccountUsername: administratorAccountUsername administratorAccountPassword: administratorAccountPassword - 'subnet-id': subnet_id + subnet_id: var_subnet_id vhds: vhds rdshImageSourceId: vmCustomImageSourceId location: vmLocation @@ -312,15 +311,114 @@ module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json aadJoin: aadJoin intune: intune bootDiagnostics: bootDiagnostics - '_guidValue': deploymentId + guidValue: deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: (contains(systemData, 'hostpoolUpdate') ? systemData.sessionHostConfigurationVersion : '') + } +} + +module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = if (vmTemplateUri == 'managedDisks-galleryvm.bicep') { + name: 'vmCreation_managed_galleryvm-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + subnet_id: var_subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + vmInitialNumber: vmInitialNumber + hostpoolName: hostpoolName + hostpoolToken: hostpoolToken + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + guidValue: deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: (contains(systemData, 'hostpoolUpdate') ? systemData.sessionHostConfigurationVersion : '') + } +} + +module vmCreation_unmanaged_customvhd '../nestedtemplates/unmanagedDisks-customvhdvm.bicep' = if (vmTemplateUri == 'unmanagedDisks-customvhdvm.bicep') { + name: 'vmCreation_unmanaged_customvhd-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + subnet_id: var_subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + vmInitialNumber: vmInitialNumber + hostpoolName: hostpoolName + hostpoolToken: hostpoolToken + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + guidValue: deploymentId userAssignedIdentity: userAssignedIdentity customConfigurationTemplateUrl: customConfigurationTemplateUrl customConfigurationParameterUrl: customConfigurationParameterUrl SessionHostConfigurationVersion: (contains(systemData, 'hostpoolUpdate') ? systemData.sessionHostConfigurationVersion : '') } - dependsOn: [ - AVSet_linkedTemplate_deploymentId - ] } output rdshVmNamesObject object = rdshVmNamesOutput diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 3b562b0e1..81c9133b7 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -1,5 +1,5 @@ @description('The base URI where artifacts required by this template are located.') -param nestedTemplatesLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/nestedtemplates/' +param nestedTemplatesLocation string = '..\nestedtemplates' @description('The base URI where artifacts required by this template are located.') param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' @@ -327,10 +327,10 @@ var rdshManagedDisks = ((vmImageType == 'CustomVHD') ? vmUseManagedDisks : bool( var rdshPrefix = '${vmNamePrefix}-' var avSetSKU = (rdshManagedDisks ? 'Aligned' : 'Classic') var vhds = 'vhds/${rdshPrefix}' -var subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) +var var_subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) var hostpoolName_var = replace(hostpoolName, '"', '') var vmTemplateName = '${(rdshManagedDisks ? 'managedDisks' : 'unmanagedDisks')}-${toLower(replace(vmImageType, ' ', ''))}vm' -var vmTemplateUri = '${nestedTemplatesLocation}${vmTemplateName}.json' +var vmTemplateUri = '${nestedTemplatesLocation}${vmTemplateName}.bicep' var rdshVmNamesCopyNamesArr = [for item in range(0, (createVMs ? vmNumberOfInstances : 1)): { name: '${rdshPrefix}${item}' }] @@ -467,9 +467,9 @@ module AVSet_linkedTemplate_deploymentId '../nestedtemplates/nested_AVSet_linked ] } -/*TODO: replace with correct path to [variables('vmTemplateUri')] Bicep currently does not "support string interpolation in FilePaths." This is going to require some deeper refactoring, Either by using BICEP PUBLISH, or keeping local copy in the GitHub repo.*/ -module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json locally to my build and convert to bicep only for workaround, ask preference next meeting*/ = if (createVMs) { - name: 'vmCreation-linkedTemplate-${deploymentId}' +/* TODO: Uncomment +module vmCreation_managed_customImagevm '../nestedtemplates/managedDisks-customimagevm.bicep' = if (createVMs && vmTemplateUri == 'managedDisks-customimagevm.bicep') { + name: 'mCreation_managed_customImagevm-${deploymentId}' scope: resourceGroup(vmResourceGroup) params: { artifactsLocation: artifactsLocation @@ -492,7 +492,7 @@ module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json vmAdministratorAccountPassword: vmAdministratorAccountPassword administratorAccountUsername: administratorAccountUsername administratorAccountPassword: administratorAccountPassword - 'subnet-id': subnet_id + subnet_id: var_subnet_id vhds: vhds rdshImageSourceId: vmCustomImageSourceId location: vmLocation @@ -510,17 +510,215 @@ module vmCreation_linkedTemplate_deploymentId '?' /*TODO: For now, can add json aadJoin: aadJoin intune: intune bootDiagnostics: bootDiagnostics - '_guidValue': deploymentId + guidValue: deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') + } +} + +module vmCreation_managed_customvhdvm '../nestedtemplates/managedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateUri == 'managedDisks-customvhdvm.bicep') { + name: 'vmCreation_managed_customvhdvm-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + subnet_id: var_subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + hostpoolToken: hostpoolName_resource.properties.registrationInfo.token + hostpoolName: hostpoolName + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + guidValue: deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') + } +} + +module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = if (createVMs && vmTemplateUri == 'managedDisks-galleryvm.bicep') { + name: 'vmCreation_managed_galleryvm-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + subnet_id: var_subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + hostpoolToken: hostpoolName_resource.properties.registrationInfo.token + hostpoolName: hostpoolName + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + guidValue: deploymentId userAssignedIdentity: userAssignedIdentity customConfigurationTemplateUrl: customConfigurationTemplateUrl customConfigurationParameterUrl: customConfigurationParameterUrl SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') } - dependsOn: [ - AVSet_linkedTemplate_deploymentId - ] } +module vmCreation_unmanaged_customvhdvm '../nestedtemplates/unmanagedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateUri == 'unmanagedDisks-customvhdvm.bicep') { + name: 'vmCreation_unmanaged_customvhdvm-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + subnet_id: var_subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + hostpoolToken: hostpoolName_resource.properties.registrationInfo.token + hostpoolName: hostpoolName + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + guidValue: deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') + } +} */ + +module vmCreation_man_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = { + name: 'vmCreation_man_galleryvm-${deploymentId}' + scope: resourceGroup(vmResourceGroup) + params: { + artifactsLocation: artifactsLocation + availabilityOption: availabilityOption + availabilitySetName: availabilitySetName + availabilityZone: availabilityZone + vmImageVhdUri: vmImageVhdUri + storageAccountResourceGroupName: storageAccountResourceGroupName + vmGalleryImageOffer: vmGalleryImageOffer + vmGalleryImagePublisher: vmGalleryImagePublisher + vmGalleryImageHasPlan: vmGalleryImageHasPlan + vmGalleryImageSKU: vmGalleryImageSKU + vmGalleryImageVersion: vmGalleryImageVersion + rdshPrefix: rdshPrefix + rdshNumberOfInstances: vmNumberOfInstances + rdshVMDiskType: vmDiskType + rdshVmSize: vmSize + enableAcceleratedNetworking: false + vmAdministratorAccountUsername: vmAdministratorAccountUsername + vmAdministratorAccountPassword: vmAdministratorAccountPassword + administratorAccountUsername: administratorAccountUsername + administratorAccountPassword: administratorAccountPassword + subnet_id: var_subnet_id + vhds: vhds + rdshImageSourceId: vmCustomImageSourceId + location: vmLocation + createNetworkSecurityGroup: createNetworkSecurityGroup + networkSecurityGroupId: networkSecurityGroupId + networkSecurityGroupRules: networkSecurityGroupRules + networkInterfaceTags: networkInterfaceTags + networkSecurityGroupTags: networkSecurityGroupTags + virtualMachineTags: virtualMachineTags + imageTags: imageTags + hostpoolToken: hostpoolName_resource.properties.registrationInfo.token + hostpoolName: hostpoolName + domain: domain + ouPath: ouPath + aadJoin: aadJoin + intune: intune + bootDiagnostics: bootDiagnostics + guidValue: deploymentId + userAssignedIdentity: userAssignedIdentity + customConfigurationTemplateUrl: customConfigurationTemplateUrl + customConfigurationParameterUrl: customConfigurationParameterUrl + SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') + } +} + + resource hostpoolName_Microsoft_Insights_diagnosticSetting 'Microsoft.DesktopVirtualization/hostpools/providers/diagnosticSettings@2017-05-01-preview' = if (sendLogsToEventHub || sendLogsToLogAnalytics || sendLogsToStorageAccount) { location: location name: '${hostpoolName}/Microsoft.Insights/diagnosticSetting' diff --git a/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep b/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep index a00782110..379dd011c 100644 --- a/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep @@ -354,7 +354,7 @@ resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachine ] }] -/*module post_deployment_custom_configuration '?' TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { +/*module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { name: 'post-deployment-custom-configuration' params: { } diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 928b87d54..1af4dcee3 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -273,9 +273,6 @@ resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-0 licenseType: 'Windows_Client' } zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) - dependsOn: [ - 'Microsoft.Network/networkInterfaces/${rdshPrefix}${(i + vmInitialNumber)}-nic' - ] }] resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { @@ -343,7 +340,7 @@ resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachine ] }] -module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be*/ = if (!empty(customConfigurationTemplateUrl)) { +/*module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { name: 'post-deployment-custom-configuration' params: { } @@ -352,4 +349,4 @@ module post_deployment_custom_configuration '?' /*TODO: replace with correct pat rdshPrefix_vmInitialNumber_AADLoginForWindows rdshPrefix_vmInitialNumber_joindomain ] -} \ No newline at end of file +}*/ diff --git a/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep b/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep index 642695789..a3753c66e 100644 --- a/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep +++ b/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep @@ -333,7 +333,8 @@ resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachine ] }] -/*module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { +//TODO: Look into custom support +/*module post_deployment_custom_configuration '?' = if (!empty(customConfigurationTemplateUrl)) { name: 'post-deployment-custom-configuration' params: { } From b32f30973273074fa754211b0e3030e53d8acce0 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 29 Jun 2022 13:42:41 -0700 Subject: [PATCH 03/17] Fixed conditional issues and implemented nested location --- .../CreateHostpoolTemplate.bicep | 78 ++++--------------- 1 file changed, 14 insertions(+), 64 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 81c9133b7..9f030087c 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -1,5 +1,5 @@ @description('The base URI where artifacts required by this template are located.') -param nestedTemplatesLocation string = '..\nestedtemplates' +param nestedTemplatesLocation string = '../nestedtemplates' @description('The base URI where artifacts required by this template are located.') param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' @@ -330,7 +330,6 @@ var vhds = 'vhds/${rdshPrefix}' var var_subnet_id = resourceId(virtualNetworkResourceGroupName, 'Microsoft.Network/virtualNetworks/subnets', existingVnetName, existingSubnetName) var hostpoolName_var = replace(hostpoolName, '"', '') var vmTemplateName = '${(rdshManagedDisks ? 'managedDisks' : 'unmanagedDisks')}-${toLower(replace(vmImageType, ' ', ''))}vm' -var vmTemplateUri = '${nestedTemplatesLocation}${vmTemplateName}.bicep' var rdshVmNamesCopyNamesArr = [for item in range(0, (createVMs ? vmNumberOfInstances : 1)): { name: '${rdshPrefix}${item}' }] @@ -404,7 +403,7 @@ resource hostpoolName_resource 'Microsoft.DesktopVirtualization/hostpools@2019-1 tags: hostpoolTags properties: (empty(customRdpProperty) ? hostpoolRequiredProps : union(hostpoolOptionalProps, hostpoolRequiredProps)) } -/*TODO: Is this type valid? It doesn't exist in Microsoft.DesktopVirtualization, but it is also referenced in the ARM template*/ + resource hostpoolName_default 'Microsoft.DesktopVirtualization/hostpools/sessionHostConfigurations@2019-12-10-preview' = if (createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) { name: '${hostpoolName}/default' properties: { @@ -441,7 +440,7 @@ resource appGroupName 'Microsoft.DesktopVirtualization/applicationgroups@2019-12 } } -module Workspace_linkedTemplate_deploymentId '..//nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep' = if (addToWorkspace) { +module Workspace_linkedTemplate_deploymentId '../nestedtemplates/nested_Workspace_linkedTemplate_deploymentId.bicep' = if (addToWorkspace) { name: 'Workspace-linkedTemplate-${deploymentId}' scope: resourceGroup(workspaceResourceGroup_var) params: { @@ -467,59 +466,9 @@ module AVSet_linkedTemplate_deploymentId '../nestedtemplates/nested_AVSet_linked ] } -/* TODO: Uncomment -module vmCreation_managed_customImagevm '../nestedtemplates/managedDisks-customimagevm.bicep' = if (createVMs && vmTemplateUri == 'managedDisks-customimagevm.bicep') { - name: 'mCreation_managed_customImagevm-${deploymentId}' - scope: resourceGroup(vmResourceGroup) - params: { - artifactsLocation: artifactsLocation - availabilityOption: availabilityOption - availabilitySetName: availabilitySetName - availabilityZone: availabilityZone - vmImageVhdUri: vmImageVhdUri - storageAccountResourceGroupName: storageAccountResourceGroupName - vmGalleryImageOffer: vmGalleryImageOffer - vmGalleryImagePublisher: vmGalleryImagePublisher - vmGalleryImageHasPlan: vmGalleryImageHasPlan - vmGalleryImageSKU: vmGalleryImageSKU - vmGalleryImageVersion: vmGalleryImageVersion - rdshPrefix: rdshPrefix - rdshNumberOfInstances: vmNumberOfInstances - rdshVMDiskType: vmDiskType - rdshVmSize: vmSize - enableAcceleratedNetworking: false - vmAdministratorAccountUsername: vmAdministratorAccountUsername - vmAdministratorAccountPassword: vmAdministratorAccountPassword - administratorAccountUsername: administratorAccountUsername - administratorAccountPassword: administratorAccountPassword - subnet_id: var_subnet_id - vhds: vhds - rdshImageSourceId: vmCustomImageSourceId - location: vmLocation - createNetworkSecurityGroup: createNetworkSecurityGroup - networkSecurityGroupId: networkSecurityGroupId - networkSecurityGroupRules: networkSecurityGroupRules - networkInterfaceTags: networkInterfaceTags - networkSecurityGroupTags: networkSecurityGroupTags - virtualMachineTags: virtualMachineTags - imageTags: imageTags - hostpoolToken: hostpoolName_resource.properties.registrationInfo.token - hostpoolName: hostpoolName - domain: domain - ouPath: ouPath - aadJoin: aadJoin - intune: intune - bootDiagnostics: bootDiagnostics - guidValue: deploymentId - userAssignedIdentity: userAssignedIdentity - customConfigurationTemplateUrl: customConfigurationTemplateUrl - customConfigurationParameterUrl: customConfigurationParameterUrl - SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') - } -} -module vmCreation_managed_customvhdvm '../nestedtemplates/managedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateUri == 'managedDisks-customvhdvm.bicep') { - name: 'vmCreation_managed_customvhdvm-${deploymentId}' +module vmCreation_managed_customImagevm '../nestedtemplates/managedDisks-customimagevm.bicep' = if (createVMs && vmTemplateName == 'managedDisks-customimagevm') { + name: 'vmCreate_man_customImagevm-${deploymentId}' scope: resourceGroup(vmResourceGroup) params: { artifactsLocation: artifactsLocation @@ -568,8 +517,8 @@ module vmCreation_managed_customvhdvm '../nestedtemplates/managedDisks-customvhd } } -module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = if (createVMs && vmTemplateUri == 'managedDisks-galleryvm.bicep') { - name: 'vmCreation_managed_galleryvm-${deploymentId}' +module vmCreation_managed_customvhdvm '../nestedtemplates/managedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateName == 'managedDisks-customvhdvm') { + name: 'vmCreae_man_customvhdvm-${deploymentId}' scope: resourceGroup(vmResourceGroup) params: { artifactsLocation: artifactsLocation @@ -618,8 +567,8 @@ module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.b } } -module vmCreation_unmanaged_customvhdvm '../nestedtemplates/unmanagedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateUri == 'unmanagedDisks-customvhdvm.bicep') { - name: 'vmCreation_unmanaged_customvhdvm-${deploymentId}' +module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = if (createVMs && vmTemplateName == 'managedDisks-galleryvm') { + name: 'vmCreate_man_galleryvm-${deploymentId}' scope: resourceGroup(vmResourceGroup) params: { artifactsLocation: artifactsLocation @@ -666,10 +615,10 @@ module vmCreation_unmanaged_customvhdvm '../nestedtemplates/unmanagedDisks-custo customConfigurationParameterUrl: customConfigurationParameterUrl SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') } -} */ +} -module vmCreation_man_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = { - name: 'vmCreation_man_galleryvm-${deploymentId}' +module vmCreation_unmanaged_customvhdvm '../nestedtemplates/unmanagedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateName == 'unmanagedDisks-customvhdvm') { + name: 'vmCreate_unman_customvhdvm-${deploymentId}' scope: resourceGroup(vmResourceGroup) params: { artifactsLocation: artifactsLocation @@ -718,7 +667,6 @@ module vmCreation_man_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep } } - resource hostpoolName_Microsoft_Insights_diagnosticSetting 'Microsoft.DesktopVirtualization/hostpools/providers/diagnosticSettings@2017-05-01-preview' = if (sendLogsToEventHub || sendLogsToLogAnalytics || sendLogsToStorageAccount) { location: location name: '${hostpoolName}/Microsoft.Insights/diagnosticSetting' @@ -765,3 +713,5 @@ resource isNewWorkspace_workSpaceName_placeholder_Microsoft_Insights_diagnosticS } output rdshVmNamesObject object = rdshVmNamesOutput +output vmPath string = vmTemplateName +output create bool = createVMs From 1a98932d20516a9e26cc63273b57aa994896b3b3 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Tue, 19 Jul 2022 16:15:02 -0700 Subject: [PATCH 04/17] Removed extra artifact location call --- .../CreateHostpoolParams.json | 173 ++++++++++++++++++ .../CreateHostpoolTemplate.bicep | 3 - 2 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json new file mode 100644 index 000000000..4d580e39b --- /dev/null +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json @@ -0,0 +1,173 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "artifactsLocation": { + "value": "https://wvdportalstorageblob.blob.core.windows.net/galleryartifacts/Configuration_05-03-2022.zip" + }, + "nestedTemplatesLocation": { + "value": "..\nestedtemplates" + }, + "tokenExpirationTime": { + "value": "2022-07-25T17:37:47.087Z" + }, + "vmTemplate": { + "value": "{\"domain\":\"wvdtesttenant.onmicrosoft.com\",\"galleryImageOffer\":\"WindowsServer\",\"galleryImagePublisher\":\"MicrosoftWindowsServer\",\"galleryImageSKU\":\"2019-Datacenter\",\"imageType\":\"Gallery\",\"imageUri\":null,\"customImageId\":null,\"namePrefix\":\"alecb-porvm\",\"osDiskType\":\"StandardSSD_LRS\",\"vmSize\":{\"id\":\"Standard_D2s_v3\",\"cores\":2,\"ram\":8},\"galleryItemId\":\"Microsoft.WindowsServer2019Datacenter\",\"hibernate\":false,\"diskSizeGB\":8}" + }, + "intune": { + "value": false + }, + "hostpoolName": { + "value": "alecb-bicep-hp" + }, + "hostpoolDescription": { + "value": "Created through the Azure Virtual Desktop extension" + }, + "location": { + "value": "eastus" + }, + "validationEnvironment": { + "value": false + }, + "hostpoolType": { + "value": "Pooled" + }, + "loadBalancerType": { + "value": "BreadthFirst" + }, + "vmResourceGroup": { + "value": "alecb-biceptest" + }, + "vmNamePrefix": { + "value": "alecb-vm" + }, + "vmLocation": { + "value": "eastus" + }, + "availabilityOption": { + "value": "AvailabilityZone" + }, + "availabilitySetName": { + "value": "" + }, + "createAvailabilitySet": { + "value": false + }, + "availabilitySetUpdateDomainCount": { + "value": 5 + }, + "availabilitySetFaultDomainCount": { + "value": 2 + }, + "availabilityZone": { + "value": 1 + }, + "vmImageType": { + "value": "Gallery" + }, + "vmSize": { + "value": "Standard_D2s_v3" + }, + "vmNumberOfInstances": { + "value": 2 + }, + "vmDiskType": { + "value": "StandardSSD_LRS" + }, + "bootDiagnostics": { + "value": { + "enabled": true + } + }, + "virtualNetworkResourceGroupName": { + "value": "alecb-biceptest" + }, + "existingVnetName": { + "value": "alecb-bicep-vnet" + }, + "existingSubnetName": { + "value": "default" + }, + "createNetworkSecurityGroup": { + "value": false + }, + "aadJoin": { + "value": false + }, + "administratorAccountUsername": { + "value": "ssb@wvdtesttenant.onmicrosoft.com" + }, + "administratorAccountPassword": { + "value": "" + }, + "domain": { + "value": "wvdtesttenant.onmicrosoft.com" + }, + "ouPath": { + "value": "" + }, + "vmAdministratorAccountUsername": { + "value": "" + }, + "vmAdministratorAccountPassword": { + "value": "" + }, + "addToWorkspace": { + "value": true + }, + "applicationGroupTags": { + "value": {} + }, + "availabilitySetTags": { + "value": {} + }, + "hostpoolTags": { + "value": {} + }, + "imageTags": { + "value": {} + }, + "networkInterfaceTags": { + "value": {} + }, + "networkSecurityGroupTags": { + "value": {} + }, + "virtualMachineTags": { + "value": {} + }, + "deploymentId": { + "value": "5a5012fd-5883-446a-ac31-ba5b33031039" + }, + "vmGalleryImageOffer": { + "value": "WindowsServer" + }, + "vmGalleryImagePublisher": { + "value": "MicrosoftWindowsServer" + }, + "vmGalleryImageSKU": { + "value": "2019-Datacenter" + }, + "vmGalleryImageHasPlan": { + "value": false + }, + "maxSessionLimit": { + "value": 9999 + }, + "workspaceResourceGroup": { + "value": "alecb-biceptest" + }, + "workspaceName": { + "value": "alecb-bicep-ws" + }, + "workspaceLocation": { + "value": "eastus" + }, + "allApplicationGroupReferences": { + "value": "" + }, + "isNewWorkspace": { + "value": true + } + } +} \ No newline at end of file diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 9f030087c..e51ef2326 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -1,6 +1,3 @@ -@description('The base URI where artifacts required by this template are located.') -param nestedTemplatesLocation string = '../nestedtemplates' - @description('The base URI where artifacts required by this template are located.') param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' From 6e53dae82f53ee85dc75777e48ec4f467140abab Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Tue, 19 Jul 2022 18:43:24 -0700 Subject: [PATCH 05/17] Added default values for required parameters --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index e51ef2326..ec4c68429 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -66,7 +66,7 @@ param isNewWorkspace bool = false param allApplicationGroupReferences string = '' @description('Whether to add applicationGroup to workspace.') -param addToWorkspace bool +param addToWorkspace bool = false @description('A username in the domain that has privileges to join the session hosts to the domain. For example, \'vmjoiner@contoso.com\'.') param administratorAccountUsername string = '' @@ -218,7 +218,7 @@ param networkSecurityGroupRules array = [] 'Personal' 'Pooled' ]) -param hostpoolType string +param hostpoolType string = 'Personal' @description('Set the type of assignment for a Personal hostpool type') @allowed([ From a28e3e6aadb5f8e4eed9d46ee9cf1788d020bcbc Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Tue, 19 Jul 2022 19:32:52 -0700 Subject: [PATCH 06/17] Added default value to location parameter --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index ec4c68429..abef8c2ca 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -48,7 +48,7 @@ param workspaceDiagnosticSettingsLogCategories array = [ ] @description('The location where the resources will be deployed.') -param location string +param location string = 'West US' @description('The name of the workspace to be attach to new Applicaiton Group.') param workSpaceName string = '' @@ -244,9 +244,9 @@ param customRdpProperty string = '' @description('The necessary information for adding more VMs to this Hostpool') param vmTemplate string = '' - +//TODO: Refactor to get datetime @description('Hostpool token expiration time') -param tokenExpirationTime string +param tokenExpirationTime string = '2022-08-15T14:23:12+00:00' @description('The tags to be assigned to the hostpool') param hostpoolTags object = { From 857f06c5c480741dd0ea639012180128d13b9852 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Tue, 19 Jul 2022 20:11:10 -0700 Subject: [PATCH 07/17] Fixing datetime --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index abef8c2ca..e7829129f 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -246,7 +246,7 @@ param customRdpProperty string = '' param vmTemplate string = '' //TODO: Refactor to get datetime @description('Hostpool token expiration time') -param tokenExpirationTime string = '2022-08-15T14:23:12+00:00' +param tokenExpirationTime string = '2022-08-15T14:23:12Z' @description('The tags to be assigned to the hostpool') param hostpoolTags object = { From 3f5b0286203aaa70408f206d11251ec51edb55c7 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Tue, 19 Jul 2022 21:49:08 -0700 Subject: [PATCH 08/17] Added dynamic datetime conversion --- .../CreateHostpoolTemplate.bicep | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index e7829129f..04048e72d 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -244,9 +244,9 @@ param customRdpProperty string = '' @description('The necessary information for adding more VMs to this Hostpool') param vmTemplate string = '' -//TODO: Refactor to get datetime -@description('Hostpool token expiration time') -param tokenExpirationTime string = '2022-08-15T14:23:12Z' + +@description('A basetime that will be used to calculate tokenExpirationTime') +param baseTime string = utcNow('u') @description('The tags to be assigned to the hostpool') param hostpoolTags object = { @@ -276,9 +276,6 @@ param virtualMachineTags object = { param imageTags object = { } -@description('WVD api version') -param apiVersion string = '2019-12-10-preview' - @description('GUID for the deployment') param deploymentId string = '' @@ -318,6 +315,8 @@ param customConfigurationParameterUrl string = '' param systemData object = { } + +var tokenExpirationTime = (dateTimeAdd(baseTime, 'P15D')) var createVMs = (vmNumberOfInstances > 0) var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) var rdshManagedDisks = ((vmImageType == 'CustomVHD') ? vmUseManagedDisks : bool('true')) From cbef51471f0dc64a1ca76b69c9fa5079f1cd85ca Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 20 Jul 2022 10:43:48 -0700 Subject: [PATCH 09/17] Added default values for image vars --- .../CreateHostpoolTemplate.bicep | 10 +++++----- .../nestedtemplates/managedDisks-galleryvm.bicep | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 04048e72d..6e53123dc 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -159,21 +159,21 @@ param vmNamePrefix string = '' 'Gallery' ]) param vmImageType string = 'Gallery' - +//TODO: Add parameters to override these default values @description('(Required when vmImageType = Gallery) Gallery image Offer.') -param vmGalleryImageOffer string = '' +param vmGalleryImageOffer string = 'Windows-10' @description('(Required when vmImageType = Gallery) Gallery image Publisher.') -param vmGalleryImagePublisher string = '' +param vmGalleryImagePublisher string = 'MicrosoftWindowsDesktop' @description('Whether the VM has plan or not') param vmGalleryImageHasPlan bool = false @description('(Required when vmImageType = Gallery) Gallery image SKU.') -param vmGalleryImageSKU string = '' +param vmGalleryImageSKU string = '20h2-evd' @description('(Required when vmImageType = Gallery) Gallery image version.') -param vmGalleryImageVersion string = '' +param vmGalleryImageVersion string = 'latest' @description('(Required when vmImageType = CustomVHD) URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') param vmImageVhdUri string = '' diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 1af4dcee3..1a2011185 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -53,10 +53,10 @@ param rdshNumberOfInstances int 'StandardSSD_LRS' 'Standard_LRS' ]) -param rdshVMDiskType string +param rdshVMDiskType string = 'Standard_LRS' @description('The size of the session host VMs.') -param rdshVmSize string = 'Standard_A2' +param rdshVmSize string = 'Standard_D2_v2' @description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') param enableAcceleratedNetworking bool = false From 6ee4a36d34fc9ad02d7d5378f0503ec884723de4 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 20 Jul 2022 11:02:49 -0700 Subject: [PATCH 10/17] Added default location vars --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 6e53123dc..86472b0ec 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -48,13 +48,13 @@ param workspaceDiagnosticSettingsLogCategories array = [ ] @description('The location where the resources will be deployed.') -param location string = 'West US' +param location string = 'westus2' @description('The name of the workspace to be attach to new Applicaiton Group.') param workSpaceName string = '' @description('The location of the workspace.') -param workspaceLocation string = '' +param workspaceLocation string = 'westus2' @description('The workspace resource group Name.') param workspaceResourceGroup string = '' @@ -141,7 +141,7 @@ param availabilityZone int = 1 param vmResourceGroup string = '' @description('The location of the session host VMs.') -param vmLocation string = '' +param vmLocation string = 'westus2' @description('The size of the session host VMs.') param vmSize string = '' From bc8333d8a905132e6fe4b2c90667b3a412c48935 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 20 Jul 2022 11:31:36 -0700 Subject: [PATCH 11/17] Added default VM size to hostpool template --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 86472b0ec..3e82c636b 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -144,7 +144,7 @@ param vmResourceGroup string = '' param vmLocation string = 'westus2' @description('The size of the session host VMs.') -param vmSize string = '' +param vmSize string = 'Standard_D2_v2' @description('Number of session hosts that will be created and added to the hostpool.') param vmNumberOfInstances int = 0 From cd00e20044afe33ca314a102659fa46cd9ce5a4f Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 20 Jul 2022 11:54:53 -0700 Subject: [PATCH 12/17] Changed size and region of vm to suggested values --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 4 ++-- bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 3e82c636b..23f5f4094 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -141,10 +141,10 @@ param availabilityZone int = 1 param vmResourceGroup string = '' @description('The location of the session host VMs.') -param vmLocation string = 'westus2' +param vmLocation string = 'eastus' @description('The size of the session host VMs.') -param vmSize string = 'Standard_D2_v2' +param vmSize string = 'Standard_D2s_v3' @description('Number of session hosts that will be created and added to the hostpool.') param vmNumberOfInstances int = 0 diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 1a2011185..319c19a72 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -56,7 +56,7 @@ param rdshNumberOfInstances int param rdshVMDiskType string = 'Standard_LRS' @description('The size of the session host VMs.') -param rdshVmSize string = 'Standard_D2_v2' +param rdshVmSize string = 'Standard_D2s_v3' @description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') param enableAcceleratedNetworking bool = false From 6ba565f187e64dd1ce4e8e6755aba8ad2e80741e Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 20 Jul 2022 12:30:49 -0700 Subject: [PATCH 13/17] Matched region with subnet's region --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 2 +- bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 23f5f4094..06a28f444 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -141,7 +141,7 @@ param availabilityZone int = 1 param vmResourceGroup string = '' @description('The location of the session host VMs.') -param vmLocation string = 'eastus' +param vmLocation string = 'southcentralus' @description('The size of the session host VMs.') param vmSize string = 'Standard_D2s_v3' diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 319c19a72..048d6fc6e 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -85,7 +85,7 @@ param subnet_id string param rdshImageSourceId string = '' @description('Location for all resources to be created in.') -param location string = '' +param location string = 'southcentralus' @description('Whether to create a new network security group or use an existing one') param createNetworkSecurityGroup bool = false From 8881977c130f799b949b84f4c065bd3f9dfab80b Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Wed, 20 Jul 2022 13:51:16 -0700 Subject: [PATCH 14/17] Updated location with available resources --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 2 +- bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 06a28f444..e0fa5e714 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -141,7 +141,7 @@ param availabilityZone int = 1 param vmResourceGroup string = '' @description('The location of the session host VMs.') -param vmLocation string = 'southcentralus' +param vmLocation string = 'westus3' @description('The size of the session host VMs.') param vmSize string = 'Standard_D2s_v3' diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 048d6fc6e..3b5da7da4 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -85,7 +85,7 @@ param subnet_id string param rdshImageSourceId string = '' @description('Location for all resources to be created in.') -param location string = 'southcentralus' +param location string = 'westus3' @description('Whether to create a new network security group or use an existing one') param createNetworkSecurityGroup bool = false From 19173f69fc6546430805295e920e4d7222ddc938 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Thu, 21 Jul 2022 09:11:23 -0700 Subject: [PATCH 15/17] Explicitly defined vnet rg --- .../CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index e0fa5e714..56ac9ad95 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -202,7 +202,7 @@ param existingVnetName string = '' param existingSubnetName string = '' @description('The resource group containing the existing virtual network.') -param virtualNetworkResourceGroupName string = '' +param virtualNetworkResourceGroupName string = 'bicep-template-rg' @description('Whether to create a new network security group or use an existing one') param createNetworkSecurityGroup bool = false From 4d48a42167b5b1bbf42be354304bc352ed8b1959 Mon Sep 17 00:00:00 2001 From: Alec Baird Date: Thu, 21 Jul 2022 09:14:40 -0700 Subject: [PATCH 16/17] Add dependsOn for NIC --- bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 3b5da7da4..1c9f496b8 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -273,6 +273,9 @@ resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-0 licenseType: 'Windows_Client' } zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) + dependsOn: [ + rdshPrefix_vmInitialNumber_nic + ] }] resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { From 6b47a741f4d4ec20ef8b4770f5b8b572a1d6b575 Mon Sep 17 00:00:00 2001 From: alecbaird Date: Fri, 5 Aug 2022 17:56:04 -0700 Subject: [PATCH 17/17] Removed Support for Custom VHD --- .../CreateHostpoolParams.json | 173 --------- .../CreateHostpoolTemplate.bicep | 100 ----- .../managedDisks-customimagevm.bicep | 11 - .../managedDisks-customvhdvm.bicep | 366 ------------------ .../managedDisks-galleryvm.bicep | 11 - .../unmanagedDisks-customvhdvm.bicep | 346 ----------------- 6 files changed, 1007 deletions(-) delete mode 100644 bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json delete mode 100644 bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep delete mode 100644 bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json deleted file mode 100644 index 4d580e39b..000000000 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolParams.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "artifactsLocation": { - "value": "https://wvdportalstorageblob.blob.core.windows.net/galleryartifacts/Configuration_05-03-2022.zip" - }, - "nestedTemplatesLocation": { - "value": "..\nestedtemplates" - }, - "tokenExpirationTime": { - "value": "2022-07-25T17:37:47.087Z" - }, - "vmTemplate": { - "value": "{\"domain\":\"wvdtesttenant.onmicrosoft.com\",\"galleryImageOffer\":\"WindowsServer\",\"galleryImagePublisher\":\"MicrosoftWindowsServer\",\"galleryImageSKU\":\"2019-Datacenter\",\"imageType\":\"Gallery\",\"imageUri\":null,\"customImageId\":null,\"namePrefix\":\"alecb-porvm\",\"osDiskType\":\"StandardSSD_LRS\",\"vmSize\":{\"id\":\"Standard_D2s_v3\",\"cores\":2,\"ram\":8},\"galleryItemId\":\"Microsoft.WindowsServer2019Datacenter\",\"hibernate\":false,\"diskSizeGB\":8}" - }, - "intune": { - "value": false - }, - "hostpoolName": { - "value": "alecb-bicep-hp" - }, - "hostpoolDescription": { - "value": "Created through the Azure Virtual Desktop extension" - }, - "location": { - "value": "eastus" - }, - "validationEnvironment": { - "value": false - }, - "hostpoolType": { - "value": "Pooled" - }, - "loadBalancerType": { - "value": "BreadthFirst" - }, - "vmResourceGroup": { - "value": "alecb-biceptest" - }, - "vmNamePrefix": { - "value": "alecb-vm" - }, - "vmLocation": { - "value": "eastus" - }, - "availabilityOption": { - "value": "AvailabilityZone" - }, - "availabilitySetName": { - "value": "" - }, - "createAvailabilitySet": { - "value": false - }, - "availabilitySetUpdateDomainCount": { - "value": 5 - }, - "availabilitySetFaultDomainCount": { - "value": 2 - }, - "availabilityZone": { - "value": 1 - }, - "vmImageType": { - "value": "Gallery" - }, - "vmSize": { - "value": "Standard_D2s_v3" - }, - "vmNumberOfInstances": { - "value": 2 - }, - "vmDiskType": { - "value": "StandardSSD_LRS" - }, - "bootDiagnostics": { - "value": { - "enabled": true - } - }, - "virtualNetworkResourceGroupName": { - "value": "alecb-biceptest" - }, - "existingVnetName": { - "value": "alecb-bicep-vnet" - }, - "existingSubnetName": { - "value": "default" - }, - "createNetworkSecurityGroup": { - "value": false - }, - "aadJoin": { - "value": false - }, - "administratorAccountUsername": { - "value": "ssb@wvdtesttenant.onmicrosoft.com" - }, - "administratorAccountPassword": { - "value": "" - }, - "domain": { - "value": "wvdtesttenant.onmicrosoft.com" - }, - "ouPath": { - "value": "" - }, - "vmAdministratorAccountUsername": { - "value": "" - }, - "vmAdministratorAccountPassword": { - "value": "" - }, - "addToWorkspace": { - "value": true - }, - "applicationGroupTags": { - "value": {} - }, - "availabilitySetTags": { - "value": {} - }, - "hostpoolTags": { - "value": {} - }, - "imageTags": { - "value": {} - }, - "networkInterfaceTags": { - "value": {} - }, - "networkSecurityGroupTags": { - "value": {} - }, - "virtualMachineTags": { - "value": {} - }, - "deploymentId": { - "value": "5a5012fd-5883-446a-ac31-ba5b33031039" - }, - "vmGalleryImageOffer": { - "value": "WindowsServer" - }, - "vmGalleryImagePublisher": { - "value": "MicrosoftWindowsServer" - }, - "vmGalleryImageSKU": { - "value": "2019-Datacenter" - }, - "vmGalleryImageHasPlan": { - "value": false - }, - "maxSessionLimit": { - "value": 9999 - }, - "workspaceResourceGroup": { - "value": "alecb-biceptest" - }, - "workspaceName": { - "value": "alecb-bicep-ws" - }, - "workspaceLocation": { - "value": "eastus" - }, - "allApplicationGroupReferences": { - "value": "" - }, - "isNewWorkspace": { - "value": true - } - } -} \ No newline at end of file diff --git a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep index 56ac9ad95..144582930 100644 --- a/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep +++ b/bicep-templates/CreateAndProvisionHostPool/CreateHostpoolTemplate.bicep @@ -513,56 +513,6 @@ module vmCreation_managed_customImagevm '../nestedtemplates/managedDisks-customi } } -module vmCreation_managed_customvhdvm '../nestedtemplates/managedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateName == 'managedDisks-customvhdvm') { - name: 'vmCreae_man_customvhdvm-${deploymentId}' - scope: resourceGroup(vmResourceGroup) - params: { - artifactsLocation: artifactsLocation - availabilityOption: availabilityOption - availabilitySetName: availabilitySetName - availabilityZone: availabilityZone - vmImageVhdUri: vmImageVhdUri - storageAccountResourceGroupName: storageAccountResourceGroupName - vmGalleryImageOffer: vmGalleryImageOffer - vmGalleryImagePublisher: vmGalleryImagePublisher - vmGalleryImageHasPlan: vmGalleryImageHasPlan - vmGalleryImageSKU: vmGalleryImageSKU - vmGalleryImageVersion: vmGalleryImageVersion - rdshPrefix: rdshPrefix - rdshNumberOfInstances: vmNumberOfInstances - rdshVMDiskType: vmDiskType - rdshVmSize: vmSize - enableAcceleratedNetworking: false - vmAdministratorAccountUsername: vmAdministratorAccountUsername - vmAdministratorAccountPassword: vmAdministratorAccountPassword - administratorAccountUsername: administratorAccountUsername - administratorAccountPassword: administratorAccountPassword - subnet_id: var_subnet_id - vhds: vhds - rdshImageSourceId: vmCustomImageSourceId - location: vmLocation - createNetworkSecurityGroup: createNetworkSecurityGroup - networkSecurityGroupId: networkSecurityGroupId - networkSecurityGroupRules: networkSecurityGroupRules - networkInterfaceTags: networkInterfaceTags - networkSecurityGroupTags: networkSecurityGroupTags - virtualMachineTags: virtualMachineTags - imageTags: imageTags - hostpoolToken: hostpoolName_resource.properties.registrationInfo.token - hostpoolName: hostpoolName - domain: domain - ouPath: ouPath - aadJoin: aadJoin - intune: intune - bootDiagnostics: bootDiagnostics - guidValue: deploymentId - userAssignedIdentity: userAssignedIdentity - customConfigurationTemplateUrl: customConfigurationTemplateUrl - customConfigurationParameterUrl: customConfigurationParameterUrl - SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') - } -} - module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.bicep' = if (createVMs && vmTemplateName == 'managedDisks-galleryvm') { name: 'vmCreate_man_galleryvm-${deploymentId}' scope: resourceGroup(vmResourceGroup) @@ -613,56 +563,6 @@ module vmCreation_managed_galleryvm '../nestedtemplates/managedDisks-galleryvm.b } } -module vmCreation_unmanaged_customvhdvm '../nestedtemplates/unmanagedDisks-customvhdvm.bicep' = if (createVMs && vmTemplateName == 'unmanagedDisks-customvhdvm') { - name: 'vmCreate_unman_customvhdvm-${deploymentId}' - scope: resourceGroup(vmResourceGroup) - params: { - artifactsLocation: artifactsLocation - availabilityOption: availabilityOption - availabilitySetName: availabilitySetName - availabilityZone: availabilityZone - vmImageVhdUri: vmImageVhdUri - storageAccountResourceGroupName: storageAccountResourceGroupName - vmGalleryImageOffer: vmGalleryImageOffer - vmGalleryImagePublisher: vmGalleryImagePublisher - vmGalleryImageHasPlan: vmGalleryImageHasPlan - vmGalleryImageSKU: vmGalleryImageSKU - vmGalleryImageVersion: vmGalleryImageVersion - rdshPrefix: rdshPrefix - rdshNumberOfInstances: vmNumberOfInstances - rdshVMDiskType: vmDiskType - rdshVmSize: vmSize - enableAcceleratedNetworking: false - vmAdministratorAccountUsername: vmAdministratorAccountUsername - vmAdministratorAccountPassword: vmAdministratorAccountPassword - administratorAccountUsername: administratorAccountUsername - administratorAccountPassword: administratorAccountPassword - subnet_id: var_subnet_id - vhds: vhds - rdshImageSourceId: vmCustomImageSourceId - location: vmLocation - createNetworkSecurityGroup: createNetworkSecurityGroup - networkSecurityGroupId: networkSecurityGroupId - networkSecurityGroupRules: networkSecurityGroupRules - networkInterfaceTags: networkInterfaceTags - networkSecurityGroupTags: networkSecurityGroupTags - virtualMachineTags: virtualMachineTags - imageTags: imageTags - hostpoolToken: hostpoolName_resource.properties.registrationInfo.token - hostpoolName: hostpoolName - domain: domain - ouPath: ouPath - aadJoin: aadJoin - intune: intune - bootDiagnostics: bootDiagnostics - guidValue: deploymentId - userAssignedIdentity: userAssignedIdentity - customConfigurationTemplateUrl: customConfigurationTemplateUrl - customConfigurationParameterUrl: customConfigurationParameterUrl - SessionHostConfigurationVersion: ((createVMs && contains(systemData, 'hostpoolUpdateFeature') && systemData.hostpoolUpdateFeature) ? hostpoolName_default.properties.version : '') - } -} - resource hostpoolName_Microsoft_Insights_diagnosticSetting 'Microsoft.DesktopVirtualization/hostpools/providers/diagnosticSettings@2017-05-01-preview' = if (sendLogsToEventHub || sendLogsToLogAnalytics || sendLogsToStorageAccount) { location: location name: '${hostpoolName}/Microsoft.Insights/diagnosticSetting' diff --git a/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep b/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep index f74a01aca..f10908e45 100644 --- a/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-customimagevm.bicep @@ -337,14 +337,3 @@ resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachine rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC ] }] - -/*module post_deployment_custom_configurations '?' TODO: replace with correct path to post_deployment custom configs = if (!empty(customConfigurationTemplateUrl)) { - name: 'post-deployment-custom-configurations' - params: { - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - rdshPrefix_vmInitialNumber_AADLoginForWindows - rdshPrefix_vmInitialNumber_joindomain - ] -} */ diff --git a/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep b/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep deleted file mode 100644 index 379dd011c..000000000 --- a/bicep-templates/nestedtemplates/managedDisks-customvhdvm.bicep +++ /dev/null @@ -1,366 +0,0 @@ -@description('The base URI where artifacts required by this template are located.') -param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' - -@description('The availability option for the VMs.') -@allowed([ - 'None' - 'AvailabilitySet' - 'AvailabilityZone' -]) -param availabilityOption string = 'None' - -@description('The name of avaiability set to be used when create the VMs.') -param availabilitySetName string = '' - -@description('The number of availability zone to be used when create the VMs.') -@allowed([ - 1 - 2 - 3 -]) -param availabilityZone int = 1 - -@description('URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') -param vmImageVhdUri string - -@description('The storage account containing the custom VHD.') -param storageAccountResourceGroupName string - -@description('(Required when vmImageType = Gallery) Gallery image Offer.') -param vmGalleryImageOffer string = '' - -@description('(Required when vmImageType = Gallery) Gallery image Publisher.') -param vmGalleryImagePublisher string = '' - -@description('Whether the VM image has a plan or not') -param vmGalleryImageHasPlan bool = false - -@description('(Required when vmImageType = Gallery) Gallery image SKU.') -param vmGalleryImageSKU string = '' - -@description('(Required when vmImageType = Gallery) Gallery image version.') -param vmGalleryImageVersion string = '' - -@description('This prefix will be used in combination with the VM number to create the VM name. This value includes the dash, so if using “rdsh” as the prefix, VMs would be named “rdsh-0”, “rdsh-1”, etc. You should use a unique prefix to reduce name collisions in Active Directory.') -param rdshPrefix string = take(toLower(resourceGroup().name), 10) - -@description('Number of session hosts that will be created and added to the hostpool.') -param rdshNumberOfInstances int - -@description('The VM disk type for the VM: HDD or SSD.') -@allowed([ - 'Premium_LRS' - 'StandardSSD_LRS' - 'Standard_LRS' -]) -param rdshVMDiskType string - -@description('The size of the session host VMs.') -param rdshVmSize string = 'Standard_A2' - -@description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') -param enableAcceleratedNetworking bool = false - -@description('The username for the domain admin.') -param administratorAccountUsername string - -@description('The password that corresponds to the existing domain username.') -@secure() -param administratorAccountPassword string - -@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') -param vmAdministratorAccountUsername string = '' - -@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') -@secure() -param vmAdministratorAccountPassword string = '' - -@description('The URL to store unmanaged disks.') -param vhds string - -@description('The unique id of the subnet for the nics.') -param subnet_id string - -@description('Resource ID of the image.') -param rdshImageSourceId string = '' - -@description('Location for all resources to be created in.') -param location string = '' - -@description('Whether to create a new network security group or use an existing one') -param createNetworkSecurityGroup bool = false - -@description('The resource id of an existing network security group') -param networkSecurityGroupId string = '' - -@description('The rules to be given to the new network security group') -param networkSecurityGroupRules array = [] - -@description('The tags to be assigned to the network interfaces') -param networkInterfaceTags object = { -} - -@description('The tags to be assigned to the network security groups') -param networkSecurityGroupTags object = { -} - -@description('The tags to be assigned to the virtual machines') -param virtualMachineTags object = { -} - -@description('The tags to be assigned to the images') -param imageTags object = { -} - -@description('VM name prefix initial number.') -param vmInitialNumber int = 0 -param guidValue string = newGuid() - -@description('The token for adding VMs to the hostpool') -param hostpoolToken string - -@description('The name of the hostpool') -param hostpoolName string - -@description('OUPath for the domain join') -param ouPath string = '' - -@description('Domain to join') -param domain string = '' - -@description('True if AAD Join, false if AD join') -param aadJoin bool = false - -@description('True if intune enrollment is selected. False otherwise') -param intune bool = false - -@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') -param bootDiagnostics object = { - enabled: false -} - -@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') -param userAssignedIdentity string = '' - -@description('ARM template that contains custom configurations to be run after the virtual machines are created.') -param customConfigurationTemplateUrl string = '' - -@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') -param customConfigurationParameterUrl string = '' - -@description('Session host configuration version of the host pool.') -param SessionHostConfigurationVersion string = '' - -var emptyArray = [] -var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) -var storageAccountType = rdshVMDiskType -var imageName_var = '${rdshPrefix}image' -var newNsgName = '${rdshPrefix}nsg-${guidValue}' -var newNsgDeploymentName_var = 'NSG-linkedTemplate-${guidValue}' -var nsgId = (createNetworkSecurityGroup ? resourceId('Microsoft.Network/networkSecurityGroups', newNsgName) : networkSecurityGroupId) -var isVMAdminAccountCredentialsProvided = ((vmAdministratorAccountUsername != '') && (vmAdministratorAccountPassword != '')) -var vmAdministratorUsername = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountUsername : first(split(administratorAccountUsername, '@'))) -var vmAdministratorPassword = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountPassword : administratorAccountPassword) -var vmAvailabilitySetResourceId = { - id: resourceId('Microsoft.Compute/availabilitySets/', availabilitySetName) -} -var planInfoEmpty = (empty(vmGalleryImageSKU) || empty(vmGalleryImagePublisher) || empty(vmGalleryImageOffer)) -var marketplacePlan = { - name: vmGalleryImageSKU - publisher: vmGalleryImagePublisher - product: vmGalleryImageOffer -} -var vmPlan = ((planInfoEmpty || (!vmGalleryImageHasPlan)) ? json('null') : marketplacePlan) -var vmIdentityType = (aadJoin ? ((!empty(userAssignedIdentity)) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : ((!empty(userAssignedIdentity)) ? 'UserAssigned' : 'None')) -var vmIdentityTypeProperty = { - type: vmIdentityType -} -var vmUserAssignedIdentityProperty = { - userAssignedIdentities: { - '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', userAssignedIdentity)}': { - } - } -} -var vmIdentity = ((!empty(userAssignedIdentity)) ? union(vmIdentityTypeProperty, vmUserAssignedIdentityProperty) : vmIdentityTypeProperty) -var postDeploymentCustomConfigurationTemplateProperty = { - mode: 'Incremental' - templateLink: { - uri: customConfigurationTemplateUrl - contentVersion: '1.0.0.0' - } -} -var postDeploymentCustomConfigurationParameterProperty = { - parametersLink: { - uri: customConfigurationParameterUrl - } -} -var customConfigurationParameter = (empty(customConfigurationParameterUrl) ? postDeploymentCustomConfigurationTemplateProperty : union(postDeploymentCustomConfigurationTemplateProperty, postDeploymentCustomConfigurationParameterProperty)) - -resource imageName 'Microsoft.Compute/images@2018-10-01' = { - name: imageName_var - location: location - tags: imageTags - properties: { - storageProfile: { - osDisk: { - osType: 'Windows' - osState: 'Generalized' - blobUri: vmImageVhdUri - storageAccountType: storageAccountType - } - } - } -} - -module newNsgDeploymentName './nested_newNsgDeploymentName.bicep' = { - name: newNsgDeploymentName_var - params: { - variables_newNsgName: newNsgName - createNetworkSecurityGroup: createNetworkSecurityGroup - location: location - networkSecurityGroupTags: networkSecurityGroupTags - networkSecurityGroupRules: networkSecurityGroupRules - } -} - -resource rdshPrefix_vmInitialNumber_nic 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, rdshNumberOfInstances): { - name: '${rdshPrefix}${(i + vmInitialNumber)}-nic' - location: location - tags: networkInterfaceTags - properties: { - ipConfigurations: [ - { - name: 'ipconfig' - properties: { - privateIPAllocationMethod: 'Dynamic' - subnet: { - id: subnet_id - } - } - } - ] - enableAcceleratedNetworking: enableAcceleratedNetworking - networkSecurityGroup: (empty(networkSecurityGroupId) ? json('null') : json('{"id": "${nsgId}"}')) - } - dependsOn: [ - newNsgDeploymentName - ] -}] - -resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, rdshNumberOfInstances): { - name: concat(rdshPrefix, (i + vmInitialNumber)) - location: location - tags: virtualMachineTags - plan: vmPlan - identity: vmIdentity - properties: { - hardwareProfile: { - vmSize: rdshVmSize - } - availabilitySet: ((availabilityOption == 'AvailabilitySet') ? vmAvailabilitySetResourceId : json('null')) - osProfile: { - computerName: concat(rdshPrefix, (i + vmInitialNumber)) - adminUsername: vmAdministratorUsername - adminPassword: vmAdministratorPassword - } - storageProfile: { - osDisk: { - createOption: 'FromImage' - managedDisk: { - storageAccountType: storageAccountType - } - } - imageReference: { - id: imageName.id - } - } - networkProfile: { - networkInterfaces: [ - { - id: resourceId('Microsoft.Network/networkInterfaces', '${rdshPrefix}${(i + vmInitialNumber)}-nic') - } - ] - } - diagnosticsProfile: { - bootDiagnostics: bootDiagnostics - } - licenseType: 'Windows_Client' - } - zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) -}] - -resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { - name: '${rdshPrefix}${(i + vmInitialNumber)}/Microsoft.PowerShell.DSC' - location: location - properties: { - publisher: 'Microsoft.Powershell' - type: 'DSC' - typeHandlerVersion: '2.73' - autoUpgradeMinorVersion: true - settings: { - modulesUrl: artifactsLocation - configurationFunction: 'Configuration.ps1\\AddSessionHost' - properties: { - hostPoolName: hostpoolName - registrationInfoToken: hostpoolToken - aadJoin: aadJoin - sessionHostConfigurationLastUpdateTime: SessionHostConfigurationVersion - } - } - } - dependsOn: [ - rdshPrefix_vmInitialNumber - ] -}] - -resource rdshPrefix_vmInitialNumber_AADLoginForWindows 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (aadJoin) { - name: '${rdshPrefix}${(i + vmInitialNumber)}/AADLoginForWindows' - location: location - properties: { - publisher: 'Microsoft.Azure.ActiveDirectory' - type: 'AADLoginForWindows' - typeHandlerVersion: '1.0' - autoUpgradeMinorVersion: true - settings: (intune ? { - mdmId: '0000000a-0000-0000-c000-000000000000' - } : json('null')) - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - ] -}] - -resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (!aadJoin) { - name: '${rdshPrefix}${(i + vmInitialNumber)}/joindomain' - location: location - properties: { - publisher: 'Microsoft.Compute' - type: 'JsonADDomainExtension' - typeHandlerVersion: '1.3' - autoUpgradeMinorVersion: true - settings: { - name: domain_var - ouPath: ouPath - user: administratorAccountUsername - restart: 'true' - options: '3' - } - protectedSettings: { - password: administratorAccountPassword - } - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - ] -}] - -/*module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { - name: 'post-deployment-custom-configuration' - params: { - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - rdshPrefix_vmInitialNumber_AADLoginForWindows - rdshPrefix_vmInitialNumber_joindomain - ] -}*/ diff --git a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep index 1c9f496b8..1282c5e0b 100644 --- a/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep +++ b/bicep-templates/nestedtemplates/managedDisks-galleryvm.bicep @@ -342,14 +342,3 @@ resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachine rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC ] }] - -/*module post_deployment_custom_configuration '?' /*TODO: replace with correct path to What should this be = if (!empty(customConfigurationTemplateUrl)) { - name: 'post-deployment-custom-configuration' - params: { - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - rdshPrefix_vmInitialNumber_AADLoginForWindows - rdshPrefix_vmInitialNumber_joindomain - ] -}*/ diff --git a/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep b/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep deleted file mode 100644 index a3753c66e..000000000 --- a/bicep-templates/nestedtemplates/unmanagedDisks-customvhdvm.bicep +++ /dev/null @@ -1,346 +0,0 @@ -@description('The base URI where artifacts required by this template are located.') -param artifactsLocation string = 'https://raw.githubusercontent.com/Azure/RDS-Templates/master/ARM-wvd-templates/DSC/Configuration.zip' - -@description('The availability option for the VMs.') -@allowed([ - 'None' - 'AvailabilitySet' - 'AvailabilityZone' -]) -param availabilityOption string = 'None' - -@description('The name of avaiability set to be used when create the VMs.') -param availabilitySetName string = '' - -@description('The number of availability zone to be used when create the VMs.') -@allowed([ - 1 - 2 - 3 -]) -param availabilityZone int = 1 - -@description('URI of the sysprepped image vhd file to be used to create the session host VMs. For example, https://rdsstorage.blob.core.windows.net/vhds/sessionhostimage.vhd') -param vmImageVhdUri string - -@description('The storage account containing the custom VHD.') -param storageAccountResourceGroupName string - -@description('(Required when vmImageType = Gallery) Gallery image Offer.') -param vmGalleryImageOffer string = '' - -@description('(Required when vmImageType = Gallery) Gallery image Publisher.') -param vmGalleryImagePublisher string = '' - -@description('Whether the VM image has a plan or not') -param vmGalleryImageHasPlan bool = false - -@description('(Required when vmImageType = Gallery) Gallery image SKU.') -param vmGalleryImageSKU string = '' - -@description('(Required when vmImageType = Gallery) Gallery image version.') -param vmGalleryImageVersion string = '' - -@description('This prefix will be used in combination with the VM number to create the VM name. This value includes the dash, so if using “rdsh” as the prefix, VMs would be named “rdsh-0”, “rdsh-1”, etc. You should use a unique prefix to reduce name collisions in Active Directory.') -param rdshPrefix string = take(toLower(resourceGroup().name), 10) - -@description('Number of session hosts that will be created and added to the hostpool.') -param rdshNumberOfInstances int - -@description('The VM disk type for the VM: HDD or SSD.') -@allowed([ - 'Premium_LRS' - 'StandardSSD_LRS' - 'Standard_LRS' -]) -param rdshVMDiskType string - -@description('The size of the session host VMs.') -param rdshVmSize string = 'Standard_A2' - -@description('Enables Accelerated Networking feature, notice that VM size must support it, this is supported in most of general purpose and compute-optimized instances with 2 or more vCPUs, on instances that supports hyperthreading it is required minimum of 4 vCPUs.') -param enableAcceleratedNetworking bool = false - -@description('The username for the domain admin.') -param administratorAccountUsername string - -@description('The password that corresponds to the existing domain username.') -@secure() -param administratorAccountPassword string - -@description('A username to be used as the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') -param vmAdministratorAccountUsername string = '' - -@description('The password associated with the virtual machine administrator account. The vmAdministratorAccountUsername and vmAdministratorAccountPassword parameters must both be provided. Otherwise, domain administrator credentials provided by administratorAccountUsername and administratorAccountPassword will be used.') -@secure() -param vmAdministratorAccountPassword string = '' - -@description('The URL to store unmanaged disks.') -param vhds string - -@description('The unique id of the subnet for the nics.') -param subnet_id string - -@description('Resource ID of the image.') -param rdshImageSourceId string = '' - -@description('Location for all resources to be created in.') -param location string = '' - -@description('Whether to create a new network security group or use an existing one') -param createNetworkSecurityGroup bool = false - -@description('The resource id of an existing network security group') -param networkSecurityGroupId string = '' - -@description('The rules to be given to the new network security group') -param networkSecurityGroupRules array = [] - -@description('The tags to be assigned to the network interfaces') -param networkInterfaceTags object = { -} - -@description('The tags to be assigned to the network security groups') -param networkSecurityGroupTags object = { -} - -@description('The tags to be assigned to the virtual machines') -param virtualMachineTags object = { -} - -@description('The tags to be assigned to the images') -param imageTags object = { -} - -@description('VM name prefix initial number.') -param vmInitialNumber int = 0 -param guidValue string = newGuid() - -@description('The token for adding VMs to the hostpool') -param hostpoolToken string - -@description('The name of the hostpool') -param hostpoolName string - -@description('OUPath for the domain join') -param ouPath string = '' - -@description('Domain to join') -param domain string = '' - -@description('True if AAD Join, false if AD join') -param aadJoin bool = false - -@description('True if intune enrollment is selected. False otherwise') -param intune bool = false - -@description('Boot diagnostics object taken as body of Diagnostics Profile in VM creation') -param bootDiagnostics object = { - enabled: false -} - -@description('The name of user assigned identity that will assigned to the VMs. This is an optional parameter.') -param userAssignedIdentity string = '' - -@description('ARM template that contains custom configurations to be run after the virtual machines are created.') -param customConfigurationTemplateUrl string = '' - -@description('Url to the ARM template parameter file for the customConfigurationTemplateUrl parameter. This input will be used when the template is ran after the VMs have been deployed.') -param customConfigurationParameterUrl string = '' - -@description('Session host configuration version of the host pool.') -param SessionHostConfigurationVersion string = '' - -var emptyArray = [] -var domain_var = ((domain == '') ? last(split(administratorAccountUsername, '@')) : domain) -var storageAccountName = split(split(vmImageVhdUri, '/')[2], '.')[0] -var storageaccount = concat(resourceId(storageAccountResourceGroupName, 'Microsoft.Storage/storageAccounts', storageAccountName)) -var newNsgName = '${rdshPrefix}nsg-${guidValue}' -var newNsgDeploymentName_var = 'NSG-linkedTemplate-${guidValue}' -var nsgId = (createNetworkSecurityGroup ? resourceId('Microsoft.Network/networkSecurityGroups', newNsgName) : networkSecurityGroupId) -var isVMAdminAccountCredentialsProvided = ((vmAdministratorAccountUsername != '') && (vmAdministratorAccountPassword != '')) -var vmAdministratorUsername = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountUsername : first(split(administratorAccountUsername, '@'))) -var vmAdministratorPassword = (isVMAdminAccountCredentialsProvided ? vmAdministratorAccountPassword : administratorAccountPassword) -var vmAvailabilitySetResourceId = { - id: resourceId('Microsoft.Compute/availabilitySets/', availabilitySetName) -} -var vmIdentityType = (aadJoin ? ((!empty(userAssignedIdentity)) ? 'SystemAssigned, UserAssigned' : 'SystemAssigned') : ((!empty(userAssignedIdentity)) ? 'UserAssigned' : 'None')) -var vmIdentityTypeProperty = { - type: vmIdentityType -} -var vmUserAssignedIdentityProperty = { - userAssignedIdentities: { - '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities/', userAssignedIdentity)}': { - } - } -} -var vmIdentity = ((!empty(userAssignedIdentity)) ? union(vmIdentityTypeProperty, vmUserAssignedIdentityProperty) : vmIdentityTypeProperty) -var postDeploymentCustomConfigurationTemplateProperty = { - mode: 'Incremental' - templateLink: { - uri: customConfigurationTemplateUrl - contentVersion: '1.0.0.0' - } -} -var postDeploymentCustomConfigurationParameterProperty = { - parametersLink: { - uri: customConfigurationParameterUrl - } -} -var customConfigurationParameter = (empty(customConfigurationParameterUrl) ? postDeploymentCustomConfigurationTemplateProperty : union(postDeploymentCustomConfigurationTemplateProperty, postDeploymentCustomConfigurationParameterProperty)) - -module newNsgDeploymentName './nested_newNsgDeploymentName.bicep' = { - name: newNsgDeploymentName_var - params: { - variables_newNsgName: newNsgName - createNetworkSecurityGroup: createNetworkSecurityGroup - location: location - networkSecurityGroupTags: networkSecurityGroupTags - networkSecurityGroupRules: networkSecurityGroupRules - } -} - -resource rdshPrefix_vmInitialNumber_nic 'Microsoft.Network/networkInterfaces@2018-11-01' = [for i in range(0, rdshNumberOfInstances): { - name: '${rdshPrefix}${(i + vmInitialNumber)}-nic' - location: location - tags: networkInterfaceTags - properties: { - ipConfigurations: [ - { - name: 'ipconfig' - properties: { - privateIPAllocationMethod: 'Dynamic' - subnet: { - id: subnet_id - } - } - } - ] - enableAcceleratedNetworking: enableAcceleratedNetworking - networkSecurityGroup: (empty(networkSecurityGroupId) ? json('null') : json('{"id": "${nsgId}"}')) - } - dependsOn: [ - newNsgDeploymentName - ] -}] - -resource rdshPrefix_vmInitialNumber 'Microsoft.Compute/virtualMachines@2020-06-01' = [for i in range(0, rdshNumberOfInstances): { - name: concat(rdshPrefix, (i + vmInitialNumber)) - location: location - tags: virtualMachineTags - identity: vmIdentity - properties: { - hardwareProfile: { - vmSize: rdshVmSize - } - availabilitySet: ((availabilityOption == 'AvailabilitySet') ? vmAvailabilitySetResourceId : json('null')) - osProfile: { - computerName: concat(rdshPrefix, (i + vmInitialNumber)) - adminUsername: vmAdministratorUsername - adminPassword: vmAdministratorPassword - } - storageProfile: { - osDisk: { - name: '${rdshPrefix}${(i + vmInitialNumber)}-osDisk' - osType: 'Windows' - caching: 'ReadWrite' - createOption: 'FromImage' - image: { - uri: vmImageVhdUri - } - vhd: { - uri: '${reference(storageaccount, '2018-11-01').primaryEndpoints.blob}${vhds}${(i + vmInitialNumber)}-osdisk.vhd' - } - } - } - networkProfile: { - networkInterfaces: [ - { - id: resourceId('Microsoft.Network/networkInterfaces', '${rdshPrefix}${(i + vmInitialNumber)}-nic') - } - ] - } - diagnosticsProfile: { - bootDiagnostics: bootDiagnostics - } - licenseType: 'Windows_Client' - } - zones: ((availabilityOption == 'AvailabilityZone') ? array(availabilityZone) : emptyArray) -}] - -resource rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): { - name: '${rdshPrefix}${(i + vmInitialNumber)}/Microsoft.PowerShell.DSC' - location: location - properties: { - publisher: 'Microsoft.Powershell' - type: 'DSC' - typeHandlerVersion: '2.73' - autoUpgradeMinorVersion: true - settings: { - modulesUrl: artifactsLocation - configurationFunction: 'Configuration.ps1\\AddSessionHost' - properties: { - hostPoolName: hostpoolName - registrationInfoToken: hostpoolToken - aadJoin: aadJoin - sessionHostConfigurationLastUpdateTime: SessionHostConfigurationVersion - } - } - } - dependsOn: [ - rdshPrefix_vmInitialNumber - ] -}] - -resource rdshPrefix_vmInitialNumber_AADLoginForWindows 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (aadJoin) { - name: '${rdshPrefix}${(i + vmInitialNumber)}/AADLoginForWindows' - location: location - properties: { - publisher: 'Microsoft.Azure.ActiveDirectory' - type: 'AADLoginForWindows' - typeHandlerVersion: '1.0' - autoUpgradeMinorVersion: true - settings: (intune ? { - mdmId: '0000000a-0000-0000-c000-000000000000' - } : json('null')) - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - ] -}] - -resource rdshPrefix_vmInitialNumber_joindomain 'Microsoft.Compute/virtualMachines/extensions@2018-10-01' = [for i in range(0, rdshNumberOfInstances): if (!aadJoin) { - name: '${rdshPrefix}${(i + vmInitialNumber)}/joindomain' - location: location - properties: { - publisher: 'Microsoft.Compute' - type: 'JsonADDomainExtension' - typeHandlerVersion: '1.3' - autoUpgradeMinorVersion: true - settings: { - name: domain_var - ouPath: ouPath - user: administratorAccountUsername - restart: 'true' - options: '3' - } - protectedSettings: { - password: administratorAccountPassword - } - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - ] -}] - -//TODO: Look into custom support -/*module post_deployment_custom_configuration '?' = if (!empty(customConfigurationTemplateUrl)) { - name: 'post-deployment-custom-configuration' - params: { - } - dependsOn: [ - rdshPrefix_vmInitialNumber_Microsoft_PowerShell_DSC - rdshPrefix_vmInitialNumber_AADLoginForWindows - rdshPrefix_vmInitialNumber_joindomain - ] -}*/