Back to Blog
DevOps
3 min read

AVD Application Group Assignments in Terraform

AzureAVDTerraformVirtual Desktop

Assigning users or groups to Azure Virtual Desktop application groups should be simple. In Terraform, it's surprisingly tricky.

The Resource

resource "azurerm_virtual_desktop_application_group" "desktop" {
  name                = "ag-desktop"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  type                = "Desktop"
  host_pool_id        = azurerm_virtual_desktop_host_pool.this.id
}

resource "azurerm_role_assignment" "avd_users" {
  scope                = azurerm_virtual_desktop_application_group.desktop.id
  role_definition_name = "Desktop Virtualization User"
  principal_id         = data.azuread_group.avd_users.object_id
}

Wait - that's a role assignment, not an application group assignment. What?

The Confusion

Azure Virtual Desktop has two concepts:

  1. RBAC role assignments - Who can use the application group
  2. Application group assignments - (Legacy) Direct user/group assignments

The modern approach uses RBAC. The Desktop Virtualization User role grants access to use the application group.

Getting the Azure AD Group

data "azuread_group" "avd_users" {
  display_name     = "AVD-Users"
  security_enabled = true
}

You need the azuread provider:

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.80"
    }
    azuread = {
      source  = "hashicorp/azuread"
      version = "~> 2.45"
    }
  }
}

provider "azuread" {
  tenant_id = var.tenant_id
}

Multiple Groups

Assign multiple groups using for_each:

variable "avd_user_groups" {
  type    = list(string)
  default = ["AVD-Users", "AVD-Admins", "Remote-Workers"]
}

data "azuread_group" "avd_groups" {
  for_each         = toset(var.avd_user_groups)
  display_name     = each.value
  security_enabled = true
}

resource "azurerm_role_assignment" "avd_access" {
  for_each             = data.azuread_group.avd_groups
  scope                = azurerm_virtual_desktop_application_group.desktop.id
  role_definition_name = "Desktop Virtualization User"
  principal_id         = each.value.object_id
}

RemoteApp Application Groups

For RemoteApp (published applications):

resource "azurerm_virtual_desktop_application_group" "remoteapp" {
  name                = "ag-apps"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  type                = "RemoteApp"
  host_pool_id        = azurerm_virtual_desktop_host_pool.this.id
}

resource "azurerm_virtual_desktop_application" "word" {
  name                         = "Word"
  application_group_id         = azurerm_virtual_desktop_application_group.remoteapp.id
  friendly_name                = "Microsoft Word"
  path                         = "C:\\Program Files\\Microsoft Office\\root\\Office16\\WINWORD.EXE"
  command_line_argument_policy = "DoNotAllow"
  show_in_portal               = true
}

Workspace Association

Don't forget to associate application groups with a workspace:

resource "azurerm_virtual_desktop_workspace" "this" {
  name                = "ws-avd"
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
}

resource "azurerm_virtual_desktop_workspace_application_group_association" "desktop" {
  workspace_id         = azurerm_virtual_desktop_workspace.this.id
  application_group_id = azurerm_virtual_desktop_application_group.desktop.id
}

Common Issues

"Principal does not exist" - The Azure AD group doesn't exist or you don't have permission to read it. Check azuread provider authentication.

"Role assignment already exists" - Use lifecycle { ignore_changes = [principal_id] } if managing assignments outside Terraform too.

Changes not taking effect - Users may need to sign out and back in. Check the Windows Remote Desktop client for updates.


Need help deploying Azure Virtual Desktop? Get in touch - we help organisations implement secure remote desktop solutions.

Need help with your Azure environment?

Get in touch for a free consultation.

Get in Touch