Deploying Windows Virtual Desktop host pools with Terraform
Published Mar 12 2020 11:29 AM 27.8K Views
Microsoft

Terraform is a tool that enables you to completely automate infrastructure builds through configuration files. It provides versioning for configurations, which makes it easy to deploy and maintain your existing Windows Virtual Desktop deployments on Microsoft Azure.

The following guide below describes how to deploy a new host pool or modify an existing host pool within Windows Virtual Desktop using Terraform.

Note: Terraform is an open source tool hosted in GitHub. As such, it is published "as is" with no implied support from Microsoft or any other organization. However, we would like to welcome you to open issues using GitHub issues to collaborate toward future improvements to the tool. Special thanks to Matt Betts for his major contribution.

Overview and requirements

The steps listed below must be completed in order to deploy a Windows Virtual Desktop host pool with Terraform.

  1. Ensure that you meet the requirements for Windows Virtual Desktop.
    1. DC/AAD DS
    2. WVD tenant must be created
    3. TenantCreator role must be assigned
    4. VNET configured with Layer 3 access to DC/AAD DS
  2. Terraform must be installed and configured as outlined here.
  3. Terraform code from GitHub repository is downloaded to a local folder.
  4. Terraform files variables.tf and variables_tags.tf are update.
  5. Terraform deployment is started. A sample process for deploying available here.
    1. terraform init
    2. terraform plan
    3. terraform apply
  6. Validate session host VMs are deployed and heart beating via Get-RdsSessionHost.

Setting up Terraform 

When you are new to Terraform. Please have a look at this article outlines the steps needed to get started with Visual Studio Code, Terraform and Azure.

Preparing Azure subscription and WVD for Terraform

Preparing the Azure subscription mean that we need to make sure that the account we are going to be used has the necessary permission to deploy new resources. Additionally, prior to updating the Terraform scripts create a resource group that will be tied to the Terraform deployment.

When it comes to WVD the preparation steps cover:

  • Granting TenantCreator to the user account we are going to be using
  • Creating a WVD tenant

Getting access to Terraform templates

To start all files that are listed in the folder must be downloaded to a local folder. All Terraform files needed for deployment are available at this repository.

Below is a brief description for each file and its purpose.

 

Availability_set.tf

This file contains the setting needed to set the availability set of VMs. In most basic deployments this file does not require changes.

 

Outputs.tf

This file displays certain variables that should be captured at the end of the execution. A detailed description of outputs in Terraforms can be found here. In most basic deployments this file does not require changes.

 

Variables.tf

This file contains all the modifiable input variables that define the behavior and outcome of running terraforms.

 

Variables_tags.tf

This file contains can be used to define custom tags as they are used throughout Terraforms. In most basic deployments this file does not require changes. This document outlines the benefits of using tags.

 

Virtual_machine.tf

This file contains code needed for setting up the individual VMs and their configuration. In most basic deployments this file does not require changes.

 

Virtual_machine_extensions.tf

This file contains code needed for running the customer script extensions that perform:

  • Domain join
  • Registration of the VM with the WVD service.

Configuring Terraform

Prior to running the Terraform variables.tf must be modified to reflect your environment. The table that follows outlines each input parameter and what is to be set to when deploying Windows Virtual Desktop.

Name

Description

Type

Default

Required

subnet_id

ID of the Subnet in which the machines will exist.

String

-

Yes

tenant_app_password

The password of the tenant app.

String

-

Yes

tenant_app_id

UPN for the user with permissions in WVD allowing for creation of a host pool (RD Contributor and/or RD Owner).

String

-

Yes

aad_tenant_id

Azure tenant ID.

String

-

Yes

ou_path

OU path to use when domain joining.

String

-

Yes

log_analytics_workspace_id

Workspace ID of the Log Analytics Workspace to associate the session host VMs to.

String

-

Yes

vm_timezone

Defines the time zone which a VM is going to use. List of time zone names available here.

String

-

Yes

log_analytics_workspace_primary_shared_key

Primary Shared Key of the Log Analytics Workspace to associate the VMs with.

String

-

Yes

resource_group_name

Name of the resource group in which Terraform will deploy resources. This group must be created manually before deploying.

String

-

Yes

region

The region in which to deploy the resources. The region must be such that the newly provisioned VM can communicate with the domain controller.

String

-

Yes

host_pool_name

Name of the session host pool.

String

-

Yes

vm_prefix

Prefix to be added to each VM as host name.

String

-

Yes

tenant_name

Name of WVD tenant.

String

-

Yes

rdsh_count

Number of session host VM to be deployed.

Int

1

Only if deploying more than 1

managed_disk_type

The type of managed disk(s) to attach.

String

Standard_LRS

No

tenantLocation

The region in which the RDS tenant exists.

String

eastus

No

vm_size

VM size. Full list of SKUs available here.

String

Standard_F2s

No

nsg_id

The ID of the NSG to associate the network interface.

String

-

No

existing_tenant_group_name

(deprecated) Name of the WVD tenant group.

String

Default Tenant Group

No

base_url

The URL in which the RDS components exists. This will need to be modified if the Github repo is forked.

String

https://raw.githubusercontent.com/Azure/RDS-Templates/master/wvd-templates

No

managed_disk_sizes

The sizes of the optional managed data disks.

List (String)

-

No

host_pool_description

Description of the session host pool.

String

Created through Terraform template

No

is_service_principal

Is a service principal being used for configuring WVD.

String

true

No

RDBrokerURL

URL of the RD Broker.

String

https://rdbroker.wvd.microsoft.com

No

as_platform_fault_domain_count

https://github.com/MicrosoftDocs/azure-docs/blob/master/includes/managed-disks-common-fault-domain-r...

Int

3

No

as_platform_update_domain_count

https://github.com/MicrosoftDocs/azure-docs/blob/master/includes/managed-disks-common-fault-domain-r...

Int

5

No

extension_bginfo

Should BGInfo be attached to all servers.

String

true

No

extension_loganalytics

Should Log Analytics agent be attached to all servers.

String

true

No

extension_custom_script

Should a custom script extension be run on all servers.

String

false

No

local_admin_username

Name of the local admin account that will be created on each of the VM.

String

rdshadm

No

domain_joined

Defines if a domain join is to be performed.

String (Bool)

true

No

registration_expiration_hours

The registration token expiration window (in hours).

String

48

No

vm_storage_os_disk_size

The size of the OS disk.

String

128

No

vm_version

Version of the VM image.

String

-

If vm_image_id is not set

vm_sku

The SKU of the VM image.

String

-

If vm_image_id is not set

vm_offer

Offer of the VM image.

String

-

If vm_image_id is not set

vm_publisher

Publisher of the base image to be used for provisioning the session host VMs.

String

-

If vm_image_id is not set

extensions_custom_script_fileuris

File URIs to be consumed by the custom script extension

List (String)

-

If extension_custom_script is set to true

extensions_custom_command

Command for the custom script extension to run

String

-

If extension_custom_script is set to true

domain_name

Domain name of the domain to which the session host VMs are to be joined.

String

-

If domain_joined is set to true

domain_user_upn

UPN of domain account that has permissions to perform domain join.

String

-

If domain_joined is set to true

domain_password

Password of the domain account that will perform the domain join.

String

-

If domain_joined is set to true

vm_image_id

ID of the custom image to use.

String

-

If no vm image attributes are set

Deploying with Terraform

This is the main section of this document as it covers the core steps needed to deploy WVD host pool with Terraform:

  1. Download or “fork” all Terraform scripts in a local directory.
  2. Open Visual Studio Code (VSC) and select File > Open Folder, and then point to the local folder where Terraform scripts have been downloaded.
  3. Update variables.tf.
  4. In VSC press Ctrl + Shift + P and select Azure Terraform: Init
  5. Once this completes Ctrl + Shift + P and select Azure Terraform: Init
  6. Press Ctrl + Shift + P and select Azure Terraform: Plan
  7. Review the generated plan
  8. Press Ctrl + Shift + P and select
  9. Azure Terraform: Apply

Troubleshooting Terraform deployment

Terraform deployment can fail in two main categories:

  1. Issues with Terraform code
  2. Issues with Desired State Configuration (DSC)

Issues with Terraform code

While it is rare to have issues with the Terraform code it is still possible, however most often errors are due to bad input in variables.tf.

  • If there are errors in the Terraform code, please file a GitHub issue.
  • If there are warning in the Terraform code feel free to ignore or address for your own instance of that code.
  • Using Terraform error messages it's a good starting point towards identifying issues with input variables

Issues with DSC

To troubleshoot this type of issue, navigate to the Azure portal and if needed reset the password on the VM that failed DSC. Once you are able to log in to the VM review the log files in the following two folders:

Note: XXX, YY, and ZZ are version numbers that will change based.

  • C:\Packages\Plugins\Microsoft.Compute.CustomScriptExtension\XXX\Downloads\YY
  • C:\WindowsAzure\Logs\Plugins\Microsoft.Compute.CustomScriptExtension\ZZZ

To walk you through the processes outlined in this post, please watch my video tutorial:

 

11 Comments
Iron Contributor

Why terraform was chosen as IaaC instead of ARM bearing in mind this comes from Microsoft.

Copper Contributor

At 7:30 in the video, what is the admin UI you're using?

 

Thanks.

Microsoft
Microsoft

@Gregory Suvalian There is plenty of ARM coverage when it comes to WVD and zero Terraform

Copper Contributor

What version of Terraform and the AzureRM provider is this intended to work on? There is no definition of these basic items.

Microsoft

Its define of the code in github.

Copper Contributor

I must be missing it then. I can't find it in any of your tf configs. Can you tell me the versions? I think you are using implicit versioning. I saw on the screen that you were using AzureRM version 2.1.0. I'm running TF 0.12.21 and seeing a lot of errors.

Copper Contributor

I guess I could not use this Terraform configuration for the WVD Spring Release, right? So far as I unterstood, is the architecture complety different.

Microsoft

@oliverroos right the PS modules hasn't been updated

Copper Contributor

I got it working. It took a fair amount of alteration to update everything. I didn't document it - just plunged in. If you post your problems, I could probably set you straight.

Copper Contributor

@2mOlaf So far I didn't try to deploy a Terraform configuration for WVD Spring Release.  Do I need just to update the script which does the "Registration of the VM with the WVD service."? Because all the other stuff isnt' WVD related, isn't it? Might you're willing to share your Terraform files?

Co-Authors
Version history
Last update:
‎Feb 01 2023 04:02 PM
Updated by: