Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Pooled Desktop (Part 2)

15 May

In the previous blog post we look at creating the Personal Desktop (1×1 mapping) using Terraform. Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Personal Desktop (Part 1) | AskAresh. In this blog post series I am going to demonstrate how to create the AVD Host Pool, Application Group and Workspace using Terraform for Pooled Desktop (1xMany)

We are going to create the following three types of configurations using Terraform:

  • Azure Virtual Desktop – Personal Desktop (1×1) – Part 1
  • Azure Virtual Desktop – Pooled Desktop (Multi-Session Full Desktop Experience) – Part 2
  • Azure Virtual Desktop – Remote App (Multi-Session Application aka Published Apps) – Part 3

Note – We are creating the Pooled Desktop in this post and in the subsequent post the other types will be created. In this post In this post I will not show case the creation of service principal and secret please refer for the Part 1 for that activity.

Pre-requisites

Following are the pre-requisites before you begin

  • An Azure subscription
  • The Terraform CLI
  • The Azure CLI
  • Permissions within the Azure Subscription for using Terraform

Terraform – Authenticating via Service Principal & Client Secret

Before running any Terraform code the following powershell (Make sure run as administrator) we will execute and store the credentials as enviornment variables. If we do this via the environment variable we dont have to store the below information within the providers.tf file. In the future blog post there are better way to store the below details and I hope to showcase them:

# PowerShell
$env:ARM_CLIENT_ID = "9e453b62-0000-0000-0000-00000006e1ac"
$env:ARM_CLIENT_SECRET = "Z318Q~00000000000000000000000000000000_"
$env:ARM_TENANT_ID = "a02e602c-0000-000-0000-0e0000008bba61"
$env:ARM_SUBSCRIPTION_ID = "7b051460-00000-00000-00000-000000ecb1"
  • Azure Subcription ID – Azure Portal Subcription copy the ID
  • Client ID – From the above step you will have the details
  • Client Secret – From the above step you will have the details
  • Tenant ID – While creating the Enterprise Apps in ADD you will have the details

Terraform Folder Structure

The following is the folder structure for the terrraform code:

Azure Virtual Desktop Pooled Desktop – Create a directory in which the below Terraform code will be published (providers.tf, main.tf, variables.tf and output.tf)

+---Config-AVD-Pooled-Desktop
|   |   main.tf
|   |   output.tf
|   |   providers.tf
|   |   variables.tf

Configure AVD – Pooled Desktop Pool – Providers.tf

Create a file named providers.tf and insert the following code:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.49.0"
    }
    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
  features {}
}

Configure AVD – Pooled Desktop Pool – main.tf

Create a file named main.tf and insert the following code. Let me explain what all we are attempting to accomplish here:

  • Create a Resource Group
  • Create a Workspace
  • Create a Host Pool (Pooled Desktops and Depth first load balancing)
  • Create a Desktop Application Group (DAG)
  • Associate Workspace and DAG
  • Assign Azure AD Group to the Desktop Application Group (DAG)
  • Assign Azure AD Group to the Resource Group for RBAC for the Session Host (Virtual Machine User Login)
# Resource group name is output when execution plan is applied.
resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.resource_group_location
  tags = var.tags
}

# Create AVD workspace
resource "azurerm_virtual_desktop_workspace" "workspace" {
  name                = var.workspace
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  friendly_name       = "${var.prefix} Workspace"
  description         = "${var.prefix} Workspace"
  tags = var.tags
}

# Create AVD host pool
resource "azurerm_virtual_desktop_host_pool" "hostpool" {
  resource_group_name      = azurerm_resource_group.rg.name
  location                 = azurerm_resource_group.rg.location
  name                     = var.hostpool
  friendly_name            = var.hostpool
  validate_environment     = true #[true false]
  start_vm_on_connect      = true
  custom_rdp_properties    = "targetisaadjoined:i:1;drivestoredirect:s:*;audiomode:i:0;videoplaybackmode:i:1;redirectclipboard:i:1;redirectprinters:i:1;devicestoredirect:s:*;redirectcomports:i:1;redirectsmartcards:i:1;usbdevicestoredirect:s:*;enablecredsspsupport:i:1;redirectwebauthn:i:1;use multimon:i:1;enablerdsaadauth:i:1;"
  description              = "${var.prefix} HostPool"
  type                     = "Pooled" #[Pooled or Personal]
  maximum_sessions_allowed = 5
  load_balancer_type       = "DepthFirst" #[BreadthFirst DepthFirst]
  tags = var.tags
scheduled_agent_updates {
  enabled = true
  timezone = "AUS Eastern Standard Time"  # Update this value with your desired timezone
  schedule {
    day_of_week = "Saturday"
    hour_of_day = 1   #[1 here means 1:00 am]
  }
}
}

resource "azurerm_virtual_desktop_host_pool_registration_info" "registrationinfo" {
  hostpool_id     = azurerm_virtual_desktop_host_pool.hostpool.id
  expiration_date = var.rfc3339
}

# Create AVD DAG
resource "azurerm_virtual_desktop_application_group" "dag" {
  resource_group_name = azurerm_resource_group.rg.name
  host_pool_id        = azurerm_virtual_desktop_host_pool.hostpool.id
  location            = azurerm_resource_group.rg.location
  type                = "Desktop"
  name                = var.app_group_name
  friendly_name       = "Desktop AppGroup"
  description         = "${var.prefix} AVD application group"
  depends_on          = [azurerm_virtual_desktop_host_pool.hostpool, azurerm_virtual_desktop_workspace.workspace]
  tags = var.tags
}

# Associate Workspace and DAG
resource "azurerm_virtual_desktop_workspace_application_group_association" "ws-dag" {
  application_group_id = azurerm_virtual_desktop_application_group.dag.id
  workspace_id         = azurerm_virtual_desktop_workspace.workspace.id
}

# Assign AAD Group to the Desktop Application Group (DAG)
resource "azurerm_role_assignment" "AVDGroupDesktopAssignment" {
  scope                = azurerm_virtual_desktop_application_group.dag.id
  role_definition_name = "Desktop Virtualization User"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

# Assign AAD Group to the Resource Group for RBAC for the Session Host
resource "azurerm_role_assignment" "RBACAssignment" {
  scope                = azurerm_resource_group.rg.id
  role_definition_name = "Virtual Machine User Login"
  principal_id         = data.azuread_group.AVDGroup.object_id
}

Configure AVD – Pooled Desktop Pool – variables.tf

Create a file named variables.tf and insert the following code:

variable "resource_group_location" {
  default     = "australiaeast"
  description = "Location of the resource group - Australia East"
}

variable "rg_name" {
  type        = string
  default     = "AE-DEV-AVD-01-PO-D-RG"
  description = "Name of the Resource group in which to deploy service objects"
}

variable "workspace" {
  type        = string
  description = "Name of the Azure Virtual Desktop workspace"
  default     = "AE-DEV-AVD-01-WS"
}

variable "hostpool" {
  type        = string
  description = "Name of the Azure Virtual Desktop host pool"
  default     = "AE-DEV-AVD-01-PO-D-HP"
}

variable "app_group_name" {
  description = "Name of the Azure Virtual Desktop application group"
  type        = string
  default     = "AE-DEV-AVD-01-DAG"
}

variable "rfc3339" {
  type        = string
  default     = "2023-05-20T12:43:13Z"  #Update this value with a future date
  description = "Registration token expiration"
}

variable "prefix" {
  type        = string
  default     = "AE-DEV-AVD-01-HP-"
  description = "Prefix of the name of the AVD machine(s)"
}

variable "tags" {
  type    = map(string)
  default = {
    Environment = "Dev"
    Department  = "IT"
    Location = "AustraliaEast"
    ServiceClass = "DEV"
    Workload = "Host Pool 01"
  }
}

data "azuread_client_config" "AzureAD" {}

data "azuread_group" "AVDGroup" {
  display_name     = "Win365-Users"  
}

Configure AVD – Pooled Desktop Pool – output.tf

Create a file named output.tf and insert the following code. This will showcase in the console what is getting deployed in form of a output.

output "azure_virtual_desktop_compute_resource_group" {
  description = "Name of the Resource group in which to deploy session host"
  value       = azurerm_resource_group.rg.name
}

output "azure_virtual_desktop_host_pool" {
  description = "Name of the Azure Virtual Desktop host pool"
  value       = azurerm_virtual_desktop_host_pool.hostpool.name
}

output "azurerm_virtual_desktop_application_group" {
  description = "Name of the Azure Virtual Desktop DAG"
  value       = azurerm_virtual_desktop_application_group.dag.name
}

output "azurerm_virtual_desktop_workspace" {
  description = "Name of the Azure Virtual Desktop workspace"
  value       = azurerm_virtual_desktop_workspace.workspace.name
}

output "location" {
  description = "The Azure region"
  value       = azurerm_resource_group.rg.location
}

data "azuread_group" "aad_group" {
  display_name = "Win365-Users"
}

output "AVD_user_groupname" {
  description = "Azure Active Directory Group for AVD users"
  value       = data.azuread_group.aad_group.display_name
}

Intialize Terraform – AVD – Pooled Desktop Pool

Run terraform init to initialize the Terraform deployment. This command downloads the Azure provider required to manage your Azure resources. (Its pulling the AzureRM and AzureAD)

terraform init -upgrade

Create Terraform Execution Plan – AVD – Pooled Desktop Pool

Run terraform plan to create an execution plan.

terraform plan -out mainavdpooled.tfplan

Apply Terraform Execution Plan – AVD – Pooled Desktop Pool

Run terraform apply to apply the execution plan to your cloud infrastructure.

terraform apply mainavdpooled.tfplan

Validate the Output in Azure Portal

Go to the Azure portal, Select Azure Virtual Desktop and Select Host pools, Application Group and Workspace created using Terraform.

Clean-up the above resources (Optional)

If you want to delete all the above resources then you can use the following commands to destroy. Run terraform plan and specify the destroy flag.

terraform plan -destroy -out mainavdpooled.destroy.tfplan

Run terraform apply to apply the execution plan.

terraform apply mainavdpooled.destroy.tfplan

The intention here is to get you quickly started with Terraform on Azure Virtual Desktop Solution:

DescriptionLinks
Setting up your computer to get started with Terrafor using PowershellInstall Terraform on Windows with Azure PowerShell
AVD Configure Azure Virtual Desktophttps://learn.microsoft.com/en-us/azure/developer/terraform/configure-azure-virtual-desktop
Terraform Learninghttps://youtube.com/playlist?list=PLLc2nQDXYMHowSZ4Lkq2jnZ0gsJL3ArAw

I hope you will find this helpful information for getting started with Terraform to deploy the Azure Virtual Desktop – Pooled Desktop. Please let me know if I have missed any steps or details, and I will be happy to update the post.

Thanks,
Aresh Sarkari

2 Responses to “Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace for Pooled Desktop (Part 2)”

Trackbacks/Pingbacks

  1. AVD Community Newsletter – 18th May 2023 – AVD Community - May 18, 2023

    […] He covers configuration of Host Pools, Application Groups and Workspace. You can read about here: Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace … and Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and […]

  2. Intune Newsletter - 19th May 2023 - Andrew Taylor - May 24, 2023

    […] Azure Virtual Desktop – Terraform – Create a Host Pool, Desktop Application Group and Workspace … […]

Leave a Reply

%d bloggers like this: