Skip to content

Commit

Permalink
Brownfield scenario to install AVD agents on existing VM (#739)
Browse files Browse the repository at this point in the history
* updates

* updates

* updates

* updates

---------

Co-authored-by: Dany Contreras <[email protected]>
  • Loading branch information
danycontre and Dany Contreras authored Feb 7, 2025
1 parent 44784f3 commit e5f50c5
Show file tree
Hide file tree
Showing 8 changed files with 2,039 additions and 1 deletion.
1,780 changes: 1,780 additions & 0 deletions workload/arm/brownfield/deployAddAvdAgents.json

Large diffs are not rendered by default.

94 changes: 94 additions & 0 deletions workload/bicep/brownfield/addAvdAgents/deploy.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
targetScope = 'resourceGroup'

// ========== //
// Parameters //
// ========== //

@sys.description('Subscription ID where to deploy session hosts. (Default: )')
param computeSubscriptionId string

@sys.description('Resource Group name where to deploy session hosts. (Default: )')
param computeRgResourceGroupName string

@sys.description('The name of the VM where the AVD agents will be installed. (Default: )')
param vmName string

@sys.description('AVD Host Pool resource ID. (Default: )')
param hostPoolResourceId string

@sys.description('Region of the VM to configure. (Default: )')
param vmLocation string

@sys.description('Resource ID of keyvault that contains credentials. (Default: )')
param keyVaultResourceId string

@sys.description('Do not modify, used to set unique value for resource deployment.')
param time string = utcNow()

// =========== //
// Variable declaration //
// =========== //
var varHostpoolSubId = split(hostPoolResourceId, '/')[2]
var varHostpoolRgName = split(hostPoolResourceId, '/')[4]
var varHostPoolName = split(hostPoolResourceId, '/')[8]
var varKeyVaultSubId = split(keyVaultResourceId, '/')[2]
var varKeyVaultRgName = split(keyVaultResourceId, '/')[4]
var varBaseScriptUri = 'https://raw.githubusercontent.com/Azure/avdaccelerator/main/workload/'
var varSessionHostConfigurationScriptUri = '${varBaseScriptUri}scripts/Set-SessionHostConfiguration.ps1'
var varSessionHostConfigurationScript = './Set-SessionHostConfiguration.ps1'
// =========== //
// Deployments //
// =========== //

// Call on the hotspool
resource hostPoolGet 'Microsoft.DesktopVirtualization/hostPools@2023-09-05' existing = {
name: varHostPoolName
scope: resourceGroup('${varHostpoolSubId}', '${varHostpoolRgName}')
}

// Hostpool update
module hostPool '../../../../avm/1.0.0/res/desktop-virtualization/host-pool/main.bicep' = {
scope: resourceGroup('${varHostpoolSubId}', '${varHostpoolRgName}')
name: 'HostPool-${time}'
params: {
name: hostPoolGet.name
friendlyName: hostPoolGet.properties.friendlyName
location: hostPoolGet.location
keyVaultResourceId: keyVaultResourceId
hostPoolType: (hostPoolGet.properties.hostPoolType == 'Personal') ? 'Personal' : (hostPoolGet.properties.hostPoolType == 'Pooled') ? 'Pooled' : null
startVMOnConnect: hostPoolGet.properties.startVMOnConnect
customRdpProperty: hostPoolGet.properties.customRdpProperty
loadBalancerType: (hostPoolGet.properties.loadBalancerType == 'BreadthFirst') ? 'BreadthFirst' : (hostPoolGet.properties.loadBalancerType == 'DepthFirst') ? 'DepthFirst' : (hostPoolGet.properties.loadBalancerType == 'Persistent') ? 'Persistent': null
maxSessionLimit: hostPoolGet.properties.maxSessionLimit
preferredAppGroupType: (hostPoolGet.properties.preferredAppGroupType == 'Desktop') ? 'Desktop' : (hostPoolGet.properties.preferredAppGroupType == 'RailApplications') ? 'RailApplications' : null
personalDesktopAssignmentType: (hostPoolGet.properties.personalDesktopAssignmentType == 'Automatic') ? 'Automatic' : (hostPoolGet.properties.personalDesktopAssignmentType == 'Direct') ? 'Direct' : null
description: hostPoolGet.properties.description
ssoadfsAuthority: hostPoolGet.properties.ssoadfsAuthority
ssoClientId: hostPoolGet.properties.ssoClientId
ssoClientSecretKeyVaultPath: hostPoolGet.properties.ssoClientSecretKeyVaultPath
validationEnvironment: hostPoolGet.properties.validationEnvironment
ring: hostPoolGet.properties.ring
tags: hostPoolGet.tags
agentUpdate: hostPoolGet.properties.agentUpdate
}
}

// call on the keyvault
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
name: split(hostPool.outputs.keyVaultTokenSecretResourceId, '/')[8]
scope: resourceGroup('${varKeyVaultSubId}', '${varKeyVaultRgName}')
}

// Apply AVD session host configurations
module sessionHostConfiguration './modules/configureSessionHost.bicep' = {
scope: resourceGroup('${computeSubscriptionId}', '${computeRgResourceGroupName}')
name: 'AVD-Agents-${vmName}-${time}'
params: {
location: vmLocation
name: vmName
hostPoolToken: keyVault.getSecret('hostPoolRegistrationToken')
baseScriptUri: varSessionHostConfigurationScriptUri
scriptName: varSessionHostConfigurationScript
}
dependsOn: []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// ========== //
// Parameters //
// ========== //

@sys.description('Extension deployment name.')
param name string

@sys.description('Location where to deploy compute services.')
param location string

@sys.description('URI for AVD session host configuration URI path.')
param baseScriptUri string

@sys.description('URI for AVD session host configuration script.')
param scriptName string

@sys.description('AVD Host Pool registration token')
@secure()
param hostPoolToken string

param IdentityServiceProvider string = 'ADDS'

// =========== //
// Variable declaration //
// =========== //
var varScriptArguments = '-AmdVmSize $false -IdentityServiceProvider ${IdentityServiceProvider} -Fslogix $false -HostPoolRegistrationToken ${hostPoolToken} -NvidiaVmSize $false -verbose'

// =========== //
// Deployments //
// =========== //
resource sessionHostConfig 'Microsoft.Compute/virtualMachines/extensions@2023-09-01' = {
name: '${name}/SessionHostConfig'
location: location
properties: {
publisher: 'Microsoft.Compute'
type: 'CustomScriptExtension'
typeHandlerVersion: '1.10'
autoUpgradeMinorVersion: true
settings: {
fileUris: array(baseScriptUri)
}
protectedSettings: {
commandToExecute: 'powershell -ExecutionPolicy Unrestricted -File ${scriptName} ${varScriptArguments}'
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// ========== //
// Parameters //
// ========== //

@description('Required. The name of the host pool.')
param hostPoolName string


// ========== //
// Deployments //
// ========== //

// Host pool.
resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2021-07-12' existing = {
name: hostPoolName
}


// ========== //
// Outputs //
// ========== //

output info object = hostPool.properties
35 changes: 35 additions & 0 deletions workload/bicep/brownfield/addAvdAgents/modules/hostPool.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// ========== //
// Parameters //
// ========== //

@description('Required. The name of the host pool.')
param hostPoolName string

@description('Required. The type of host pool.')
param hostPoolType string

@description('Required. The type of load balancer for the host pool.')
param loadBalancerType string

@description('Required. The location of the host pool.')
param location string

@description('Required. The preferred app group type for the host pool.')
param preferredAppGroupType string


// ========== //
// Deployments //
// ========== //

// Host pool.
resource hostPool 'Microsoft.DesktopVirtualization/hostPools@2021-07-12' = {
name: hostPoolName
location: location
properties: {
hostPoolType: hostPoolType
loadBalancerType: loadBalancerType
preferredAppGroupType: preferredAppGroupType
startVMOnConnect: true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using './deploy.bicep'

param computeSubscriptionId = '<compute-subscription-id>'
param computeRgResourceGroupName = '<compute-rg-resource-group-name>'
param vmName = '<vm-name>'
param hostPoolResourceId = '<host-pool-resource-id>'
param vmLocation = '<location>'
param keyVaultResourceId = '<key-vault-resource-id>'

52 changes: 52 additions & 0 deletions workload/bicep/brownfield/addAvdAgents/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Deploy AVD agents to VM

This solution will deploy the AVD agents to a VM.

## Requirements

- Permissions: below are the minimum required permissions to deploy this solution
- Virtual machine contributor
- Desktop Virtualization Host Pool Contributor
- Key Vault Contributor
- Resources: this solution assumes the following items already exists:
- Virtual Machine
- Key Vault
- Host pool

## Deployment Options

### Azure portal UI

[![Deploy to Azure (under construction)]()

### PowerShell

```powershell
New-AzSubscriptionDeployment `
-Location '<Azure location>' `
-TemplateFile 'https://raw.githubusercontent.com/Azure/avdaccelerator/main/workload/brownfield/addAvdAgents/deploy.bicep' `
-computeSubscriptionId '<ID of the subscription where the VM was created>' `
-computeRgResourceGroupName '<Resource group name where the VM was created>' `
-vmLocation '<VM location>' `
-vmName '<VM name>' `
-hostPoolResourceId '<resource ID of the host pool to which the VM will be registered>' `
-keyVaultResourceId '<resource ID of the key vault where the host pool registration token will be stored>' `
-Verbose
```

### Azure CLI

```azurecli
az deployment sub create \
--location '<Azure location>' \
--template-uri 'https://raw.githubusercontent.com/Azure/avdaccelerator/main/workload/brownfield/addAvdAgents/deploy.bicep' \
--parameters \
computeSubscriptionId '<ID of the subscription where the VM was created>' \
computeRgResourceGroupName '<Resource group name where the VM was created>' \
vmLocation '<VM location>' \
vmName '<VM name>' \
hostPoolResourceId '<resource ID of the host pool to which the VM will be registered>' \
keyVaultResourceId '<resource ID of the key vault where the host pool registration token will be stored>'
```
1 change: 0 additions & 1 deletion workload/scripts/Set-SessionHostConfiguration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,6 @@ try {
##############################################################
# Install the AVD Agent
##############################################################
# Disabling this method for installing the AVD agent until EntraID Join can completed successfully
$BootInstaller = 'AVD-Bootloader.msi'
Get-WebFile -FileName $BootInstaller -URL 'https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrxrH'
Start-Process -FilePath 'msiexec.exe' -ArgumentList "/i $BootInstaller /quiet /qn /norestart /passive" -Wait -Passthru
Expand Down

0 comments on commit e5f50c5

Please sign in to comment.