Azure Virtual Desktop: Session Host unable to join Azure Active Directory using Terraform

Khoi Vo 30 Reputation points
2023-12-07T07:36:29.65+00:00

Hello, I am using Terraform to provision an Azure Virtual Desktop that includes a Host Pool, Session Host, Workspace, and other resources. On my local machine, I create multiple workspaces for each environment (Test, Dev, Demo).

Initially, I was able to provision the Azure Virtual Desktop in my Test workspace, and the Session Host was able to join the Microsoft AAD successfully. However, after destroying and redeploying the resources for testing purposes, the Session Host is now in an UNAVAILABLE state and cannot join the AAD.

Interestingly, when I change the name of the Terraform variable from "Test" to "Tested" or "Testing," the Session Host can join the AAD. I am unsure why this is happening and would appreciate some guidance on how to fix it.

Azure Virtual Machines
Azure Virtual Machines
An Azure service that is used to provision Windows and Linux virtual machines.
9,016 questions
Azure Virtual Desktop
Azure Virtual Desktop
A Microsoft desktop and app virtualization service that runs on Azure. Previously known as Windows Virtual Desktop.
1,835 questions
Microsoft Security | Microsoft Entra | Microsoft Entra ID
{count} votes

Accepted answer
  1. George Mitii 75 Reputation points
    2024-08-20T13:31:56.65+00:00

    This was helpful. I was also having an issue with the VM displaying as "Unavailable" under the session hosts blade. The following is part of my Terraform (v.3.116.0) code that I used to solve this. Many thanks to @Khoi Vo.

    
    resource "azurerm_public_ip" "Public_IP" {
      for_each  = var.vmMap
      
      name                = each.value.PublicIPName
      location            = var.location
      resource_group_name = var.resourcegroup
      allocation_method   = "Dynamic"
      tags                = var.tags
    }
    
    resource "azurerm_network_interface" "NIC" {
      for_each  = var.vmMap
      
      name                = each.value.NICName
      location            = var.location
      resource_group_name = var.resourcegroup
      tags                = var.tags
    
      ip_configuration {
        name                          = "prvtIP-nicWinVM"
        subnet_id                     = each.value.Subnet01ID
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.Public_IP[each.key].id
      }
    }
    
    
    # ------------------------------------  Windows Virtual Machines -----------------------------------
    
    resource "azurerm_windows_virtual_machine" "Session_VirtualMachine" {    
      for_each  = var.vmMap
      
      name                = each.value.winVMName
      resource_group_name = var.resourcegroup
      location            = var.location
      size                = each.value.VMSize
      provision_vm_agent  = true                # Default = "true"
      #timezone            = "Central Standard Time"
      admin_username      = each.value.admin_Usr_Name
      admin_password      = each.value.admin_Passwd
    
      identity {
        type = "SystemAssigned"
      }
    
      network_interface_ids = [
        azurerm_network_interface.NIC[each.key].id,        // Implicit dependency
      ]
    
      os_disk {
        name                 = "${each.value.winVMName}-os_disk"
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
    /*
        boot_diagnostics {
        storage_account_uri = ""                               # Passing a null value will utilize a Managed Storage Account to store Boot Diagnostics
      }
    */
    
      source_image_reference {
        publisher = each.value.source_image_reference.publisher
        offer     = each.value.source_image_reference.offer
        sku       = each.value.source_image_reference.sku
        version   = each.value.source_image_reference.version
      }
        
      tags                = var.tags
    }
    
    
    # Null resource to introduce a delay (using PowerShell for Windows). This may be ignored.
    # Update this block if you are using Linux (Bash) to deploy
    
    resource "null_resource" "wait_for_vm" {
      provisioner "local-exec" {
        command = "powershell -Command \"Start-Sleep -Seconds 120\""  # Wait for 120 seconds
      }
    
      depends_on = [azurerm_windows_virtual_machine.Session_VirtualMachine]
    }
    
    
    
    # ---------   Deploy AVD Agent and associate the VM to a Session Host   ----------------
    
    resource "azurerm_virtual_machine_extension" "avd_agent_registration" {
      for_each            = var.vmMap
    
      name                = each.value.avdagentname  # avdagentregistration
      virtual_machine_id  = azurerm_windows_virtual_machine.Session_VirtualMachine[each.key].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_01-19-2023.zip",
          "ConfigurationFunction": "Configuration.ps1\\AddSessionHost",
          "Properties": {
            "hostPoolName":"${var.HPoolName}",
            "aadjoin": true
          }
        }
      SETTINGS
    
      protected_settings = <<PROTECTED_SETTINGS
      {
        "properties": {
          "registrationInfoToken": "${var.RegistrationToken}"
        }
      }
    PROTECTED_SETTINGS
    
      depends_on    = [
        azurerm_windows_virtual_machine.Session_VirtualMachine,
        null_resource.wait_for_vm
      ]
    }
    
    
    resource "azurerm_virtual_machine_extension" "AADLoginForWindows" {
      for_each            = var.vmMap
    
      name                       = each.value.sec_avdagentname
      virtual_machine_id         = azurerm_windows_virtual_machine.Session_VirtualMachine[each.key].id
      publisher                  = "Microsoft.Azure.ActiveDirectory"
      type                       = "AADLoginForWindows"
      type_handler_version       = "1.0"
      auto_upgrade_minor_version = true
    
      depends_on    = [
        azurerm_windows_virtual_machine.Session_VirtualMachine,
        null_resource.wait_for_vm
      ]
    }
    
    
    
    
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Johan Vanneuville 91 Reputation points MVP
    2023-12-11T07:59:44.1833333+00:00

    I encountered the same issue with the AAD join, try deleting the old object first from Entra ID en deploy the session hosts again using the same name.

    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.