Terraform - Deploying WVD in Azure

Lately, I've been playing around with Windows Virtual Desktop (WVD) in my personal sandbox. I wanted to see if I could build a full WVD architecture in Azure using Terraform. Microsoft has a GitHub repository containing Terraform code, but it only focuses on the Session Hosts. Also, there's a few small problems with the repo. For one, it's using old Terraform resource types that have been superseded by newer resource types (for example, azurerm_virtual_machine vs. azurerm_windows_virtual_machine). Second, it's using the old-style Terraform expression syntax. In a nutshell, the repo was pretty much useless for me. So, I began to write some new Terraform code from scratch which would deploy everything involved with the new ARM-based version of Azure WVD. In this article I plan to document some of the challenges I ran into and some of my findings.

WVD Building Blocks

Let's start with the basic building blocks of WVD. If you know WVD architecture these are all pretty self-explanatory, but I have a couple of notes for each one.

  • azurerm_virtual_desktop_host_pool : A registration token is automatically generated for the Host Pool (the Session Hosts require this token in order to join the Host Pool). You can give this token a specific expiration date, but it must be within a certain range. It has to be 1 hour into the future at a minimum, and can not be longer than 27 days into the future.
  • azurerm_virtual_desktop_application_group : Not much to note here. All you can do is create an Application Group. If you create a 'Desktop' Application Group, then it will automatically create the default desktop Application for you. If you create a 'RemoteApp' Application Group, then you must add your Applications separately, more on that below.
  • azurerm_virtual_desktop_workspace : This simply creates a Workspace, nothing to note here.
  • azurerm_virtual_desktop_workspace_application_group_association : This connects a Application Group to a Workspace, nothing to note here.

As of the writing of this article, there is no method in Terraform to create RemoteApp Applications in an Application Group. As an alternative, you could look into the Az PowerShell Module and the New-AzWvdApplication cmdlet, which lets you create RemoteApp Applications.

WVD Session Hosts

Next, you will need to focus on getting your Session Hosts created and connected to your Host Pool. You can use Terraform to create your virtual machines using the standard azurerm_windows_virtual_machine module. You will also want to create 2 azurerm_virtual_machine_extension resources per VM. One extension will be used to join the VM to your AD DS / Azure AD DS domain. The other extension will run PowerShell Desired State Configuration (DSC) on the VM to install the WVD agents and to register the machine to the Host Pool.

Here are the settings that you will need to configure for the domain-join extension. Please do NOT put plain-text passwords in your Terraform code. Also, you can set "OUPath" to an empty string, which will place the new computer objects into the default Computers container in AD.

name                       = "vm1_extension_domainjoin"
virtual_machine_id         = azurerm_windows_virtual_machine.vm1.id
publisher                  = "Microsoft.Compute"
type                       = "JsonADDomainExtension"
type_handler_version       = "1.3"
auto_upgrade_minor_version = true


settings = <<SETTINGS
  {
    "Name": "domain.com",
    "OUPath": "OU=secondlevel,OU=firstlevel,DC=domain,DC=com",
    "User": "[email protected]",
    "Restart": "true",
    "Options": "3"
    }
SETTINGS


protected_settings = <<PSETTINGS
  {
    "Password":"AdminPasswordGoesHere"
  }
PSETTINGS


lifecycle {
    ignore_changes = [ settings, protected_settings ]
}

Here are the settings you will need to configure for the PowerShell DSC extension. In order to figure out these settings, I ran through a WVD deployment using the Azure Portal, but before hitting the final 'go' I saved the deployment as a template. I then reversed engineered the template to see what its doing. As you can see it is calling out to the internet to an official Microsoft blob storage account to grab a Configuration.zip file. All of the magic is contained within this zip file, including the WVD Agents and the PowerShell scripts to make sure everything gets installed and configured correctly on the Session Host.

name                       = "vm1_extension_dsc"
virtual_machine_id         = azurerm_windows_virtual_machine.vm1.id
publisher                  = "Microsoft.Powershell"
type                       = "DSC"
type_handler_version       = "2.73"
auto_upgrade_minor_version = true
  
settings = <<SETTINGS
  {
    "modulesUrl": "https://wvdportalstorageblob.blob.core.windows.net/galleryartifacts/Configuration.zip",
    "configurationFunction": "Configuration.ps1\\AddSessionHost",
    "properties": {
      "hostPoolName": "HostPoolNameGoesHere",
      "registrationInfoToken": "${azurerm_virtual_desktop_host_pool.pool1.registration_info[0].token}"
    }
  }
SETTINGS


lifecycle {
  ignore_changes = [ settings ]
}


depends_on = [ azurerm_virtual_machine_extension.vm1_extension_domainjoin ]

Putting it all together and final steps

By now you should be in pretty good shape. You have Host Pools created, Session Hosts created and registered with a Host Pool, Workspaces created, and Application Groups created and registered to Workspaces. You might also have some RemoteApp Applications that you created via PowerShell. So, what's left? There's only one step left and that's to assign users to Application Groups.

Assigning users to Application Groups can be done with Terraform by way of the azurerm_role_assignment module. Just assign an Azure AD user account / group to the "Desktop Virtualization User" role and scope it to the Application Group in question. Here's an example:

scope                = azurerm_virtual_desktop_application_group.appgroup1.id
role_definition_name = "Desktop Virtualization User"
principal_id         = "userIDorGroupIDgoesHere"

We're almost done, we have one scenario where you need to do one final step. If you are running a Host Pool of type "Personal" and you have it configured for "Direct" assignment, then you must also assign users to their dedicated Session Host. There's no way to do this in Terraform as of now. We'll have to fall back to PowerShell again, but this time it's the Update-AzWvdSessionHost cmdlet. See this Microsoft link for more details.

Did I miss anything?

This is only piece of puzzle left to be solved

回复
Nathan Nellans

Microsoft MVP | Azure | Kubernetes | Infrastructure as Code

4 年

I uploaded some sample code to my GitHub: https://github.com/nnellans/terraform-wvd

要查看或添加评论,请登录

Nathan Nellans的更多文章

  • Quick Primer on the PowerShell shell

    Quick Primer on the PowerShell shell

    Microsoft defines PowerShell as being made up of three main components. First, it is a modern command shell.

    1 条评论
  • Which Azure service to use?

    Which Azure service to use?

    Azure has a ton of services to pick from. You can see the full list here: https://azure.

  • Kubernetes - kubectl & kubeconfig Files

    Kubernetes - kubectl & kubeconfig Files

    kubectl is the command-line tool that is used to interact with Kubernetes clusters. But, how does kubectl know which…

    3 条评论
  • Kubernetes - API Versions & Resources

    Kubernetes - API Versions & Resources

    When I sat down to write this article, it was originally titled Top 4 things that confused me about Kubernetes…

  • Azure DevOps YAML Pipelines

    Azure DevOps YAML Pipelines

    Multi-Stage CI/CD YAML Pipelines are a fairly new feature in Azure DevOps. They offer some great advantages versus the…

    2 条评论
  • All about Azure Cloud Shell

    All about Azure Cloud Shell

    Azure Cloud Shell is an interactive, in-browser shell environment. It has two different shell experiences, either Bash…

    2 条评论
  • How to connect Terraform Cloud with both Azure and Azure DevOps Services

    How to connect Terraform Cloud with both Azure and Azure DevOps Services

    This article is sort of like a Part 2. You see, I wrote a previous article that discussed connecting Terraform Cloud…

    3 条评论
  • Azure Storage Options

    Azure Storage Options

    When you create a new Storage Account in Azure you will find there are a lot of different options to select from. It…

  • Overview of email security options: SPF, DKIM, and DMARC

    Overview of email security options: SPF, DKIM, and DMARC

    If you send emails from your own custom domain name then you should really think about implementing all 3 of these…

  • Active Directory Domain Services options in Azure

    Active Directory Domain Services options in Azure

    I have a long history of working with traditional Active Directory Domain Services (AD DS). I am very familiar when it…

社区洞察

其他会员也浏览了