Konfigurera Azure Virtual Desktop-sessionsvärdar med Terraform

Den här artikeln visar hur du skapar sessionsvärdar och distribuerar dem till en AVD-värdpool med Terraform. Den här artikeln förutsätter att du redan har distribuerat Azure Virtual Desktop-infrastrukturen.

Artikel testad med följande Terraform- och Terraform-providerversioner:

Läs mer om hur du använder Terraform i Azure

I den här artikeln kan du se hur du:

  • Använda Terraform för att skapa nätverkskort för varje sessionsvärd
  • Använda Terraform för att skapa en virtuell dator för sessionsvärden
  • Ansluta virtuell dator till domän
  • Registrera virtuell dator med Azure Virtual Desktop
  • Använda variabelfil

1. Konfigurera din miljö

  • Azure-prenumeration: Om du inte har någon Azure-prenumeration kan du skapa ett kostnadsfritt konto innan du börjar.

2. Implementera Terraform-koden

  1. Skapa en katalog där du kan testa Terraform-exempelkoden och göra den till den aktuella katalogen.

  2. Skapa en fil med namnet providers.tf och infoga följande kod.

    terraform {
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>2.0"
        }
        azuread = {
          source = "hashicorp/azuread"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    

    Viktiga punkter:

    • Använd count för att ange hur många resurser som ska skapas
    • Refererar till resurser som skapades när infrastrukturen skapades – till exempel azurerm_subnet.subnet.id och azurerm_virtual_desktop_host_pool.hostpool.name. Om du har ändrat namnet på dessa resurser från det avsnittet måste du också uppdatera referenserna här.
  3. Skapa en fil med namnet main.tf och infoga följande kod:

    locals {
      registration_token = azurerm_virtual_desktop_host_pool_registration_info.registrationinfo.token
    }
    
    resource "random_string" "AVD_local_password" {
      count            = var.rdsh_count
      length           = 16
      special          = true
      min_special      = 2
      override_special = "*!@#?"
    }
    
    resource "azurerm_resource_group" "rg" {
      name     = var.rg
      location = var.resource_group_location
    }
    
    resource "azurerm_network_interface" "avd_vm_nic" {
      count               = var.rdsh_count
      name                = "${var.prefix}-${count.index + 1}-nic"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
    
      ip_configuration {
        name                          = "nic${count.index + 1}_config"
        subnet_id                     = azurerm_subnet.subnet.id
        private_ip_address_allocation = "dynamic"
      }
    
      depends_on = [
        azurerm_resource_group.rg
      ]
    }
    
    resource "azurerm_windows_virtual_machine" "avd_vm" {
      count                 = var.rdsh_count
      name                  = "${var.prefix}-${count.index + 1}"
      resource_group_name   = azurerm_resource_group.rg.name
      location              = azurerm_resource_group.rg.location
      size                  = var.vm_size
      network_interface_ids = ["${azurerm_network_interface.avd_vm_nic.*.id[count.index]}"]
      provision_vm_agent    = true
      admin_username        = var.local_admin_username
      admin_password        = var.local_admin_password
    
      os_disk {
        name                 = "${lower(var.prefix)}-${count.index + 1}"
        caching              = "ReadWrite"
        storage_account_type = "Standard_LRS"
      }
    
      source_image_reference {
        publisher = "MicrosoftWindowsDesktop"
        offer     = "Windows-10"
        sku       = "20h2-evd"
        version   = "latest"
      }
    
      depends_on = [
        azurerm_resource_group.rg,
        azurerm_network_interface.avd_vm_nic
      ]
    }
    
    resource "azurerm_virtual_machine_extension" "domain_join" {
      count                      = var.rdsh_count
      name                       = "${var.prefix}-${count.index + 1}-domainJoin"
      virtual_machine_id         = azurerm_windows_virtual_machine.avd_vm.*.id[count.index]
      publisher                  = "Microsoft.Compute"
      type                       = "JsonADDomainExtension"
      type_handler_version       = "1.3"
      auto_upgrade_minor_version = true
    
      settings = <<SETTINGS
        {
          "Name": "${var.domain_name}",
          "OUPath": "${var.ou_path}",
          "User": "${var.domain_user_upn}@${var.domain_name}",
          "Restart": "true",
          "Options": "3"
        }
    SETTINGS
    
      protected_settings = <<PROTECTED_SETTINGS
        {
          "Password": "${var.domain_password}"
        }
    PROTECTED_SETTINGS
    
      lifecycle {
        ignore_changes = [settings, protected_settings]
      }
    
      depends_on = [
        azurerm_virtual_network_peering.peer1,
        azurerm_virtual_network_peering.peer2
      ]
    }
    
    resource "azurerm_virtual_machine_extension" "vmext_dsc" {
      count                      = var.rdsh_count
      name                       = "${var.prefix}${count.index + 1}-avd_dsc"
      virtual_machine_id         = azurerm_windows_virtual_machine.avd_vm.*.id[count.index]
      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_09-08-2022.zip",
          "configurationFunction": "Configuration.ps1\\AddSessionHost",
          "properties": {
            "HostPoolName":"${azurerm_virtual_desktop_host_pool.hostpool.name}"
          }
        }
    SETTINGS
    
      protected_settings = <<PROTECTED_SETTINGS
      {
        "properties": {
          "registrationInfoToken": "${local.registration_token}"
        }
      }
    PROTECTED_SETTINGS
    
      depends_on = [
        azurerm_virtual_machine_extension.domain_join,
        azurerm_virtual_desktop_host_pool.hostpool
      ]
    }
    
  4. Skapa en fil med namnet variables.tf och infoga följande kod:

variable "resource_group_location" {
  default     = "eastus"
  description = "Location of the resource group."
}

variable "rg" {
  type        = string
  default     = "rg-avd-compute"
  description = "Name of the Resource group in which to deploy session host"
}

variable "rdsh_count" {
  description = "Number of AVD machines to deploy"
  default     = 2
}

variable "prefix" {
  type        = string
  default     = "avdtf"
  description = "Prefix of the name of the AVD machine(s)"
}

variable "domain_name" {
  type        = string
  default     = "infra.local"
  description = "Name of the domain to join"
}

variable "domain_user_upn" {
  type        = string
  default     = "domainjoineruser" # do not include domain name as this is appended
  description = "Username for domain join (do not include domain name as this is appended)"
}

variable "domain_password" {
  type        = string
  default     = "ChangeMe123!"
  description = "Password of the user to authenticate with the domain"
  sensitive   = true
}

variable "vm_size" {
  description = "Size of the machine to deploy"
  default     = "Standard_DS2_v2"
}

variable "ou_path" {
  default = ""
}

variable "local_admin_username" {
  type        = string
  default     = "localadm"
  description = "local admin username"
}

variable "local_admin_password" {
  type        = string
  default     = "ChangeMe123!"
  description = "local admin password"
  sensitive   = true
}
  1. Skapa en fil med namnet output.tf och infoga följande kod:
output "location" {
  description = "The Azure region"
  value       = azurerm_resource_group.rg.location
}

output "session_host_count" {
  description = "The number of VMs created"
  value       = var.rdsh_count
}

output "dnsservers" {
  description = "Custom DNS configuration"
  value       = azurerm_virtual_network.vnet.dns_servers
}

output "vnetrange" {
  description = "Address range for deployment vnet"
  value       = azurerm_virtual_network.vnet.address_space
}
  1. Skapa en fil med namnet terraform.tfvars och infoga följande kod:

    # Customized the sample values below for your environment and either rename to terraform.tfvars or env.auto.tfvars
    
    deploy_location      = "west europe"
    rg_name              = "avd-resources-rg"
    prefix               = "avdtf"
    local_admin_username = "localadm"
    local_admin_password = "ChangeMe123$"
    vnet_range           = ["10.1.0.0/16"]
    subnet_range         = ["10.1.0.0/24"]
    dns_servers          = ["10.0.1.4", "168.63.129.16"]
    aad_group_name       = "AVDUsers"
    domain_name          = "infra.local"
    domain_user_upn      = "admin"     # do not include domain name as this is appended
    domain_password      = "ChangeMe123!"
    ad_vnet              = "infra-network"
    ad_rg                = "infra-rg"
    avd_users = [
      "avduser01@infra.local",
      "avduser01@infra.local"
    ]
    

3. Initiera Terraform

Kör terraform init för att initiera Terraform-distributionen. Det här kommandot laddar ned den Azure-provider som krävs för att hantera dina Azure-resurser.

terraform init -upgrade

Viktiga punkter:

  • Parametern -upgrade uppgraderar nödvändiga provider-plugin-program till den senaste versionen som uppfyller konfigurationens versionsbegränsningar.

4. Skapa en Terraform-körningsplan

Kör terraform-planen för att skapa en körningsplan.

terraform plan -out main.tfplan

Viktiga punkter:

  • Kommandot terraform plan skapar en körningsplan, men kör den inte. I stället avgör den vilka åtgärder som krävs för att skapa den konfiguration som anges i konfigurationsfilerna. Med det här mönstret kan du kontrollera om körningsplanen matchar dina förväntningar innan du gör några ändringar i faktiska resurser.
  • Med den valfria -out parametern kan du ange en utdatafil för planen. Med hjälp av parametern -out ser du till att planen du granskade är exakt vad som tillämpas.

5. Tillämpa en Terraform-körningsplan

Kör terraform gäller för att tillämpa körningsplanen på din molninfrastruktur.

terraform apply main.tfplan

Viktiga punkter:

  • terraform apply Exempelkommandot förutsätter att du tidigare körde terraform plan -out main.tfplan.
  • Om du har angett ett annat filnamn för parametern -out använder du samma filnamn i anropet till terraform apply.
  • Om du inte använde parametern -out anropar terraform apply du utan några parametrar.

6. Kontrollera resultatet

  1. I Azure-portalen väljer du Azure Virtual Desktop.
  2. Välj Värdpooler och sedan Namnet på den pool som skapade resursen.
  3. Välj Sessionsvärdar och kontrollera sedan att sessionsvärden visas.

7. Rensa resurser

Gör följande när du inte längre behöver de resurser som skapats via Terraform:

  1. Kör terraform-plan och ange destroy flaggan.

    terraform plan -destroy -out main.destroy.tfplan
    

    Viktiga punkter:

    • Kommandot terraform plan skapar en körningsplan, men kör den inte. I stället avgör den vilka åtgärder som krävs för att skapa den konfiguration som anges i konfigurationsfilerna. Med det här mönstret kan du kontrollera om körningsplanen matchar dina förväntningar innan du gör några ändringar i faktiska resurser.
    • Med den valfria -out parametern kan du ange en utdatafil för planen. Med hjälp av parametern -out ser du till att planen du granskade är exakt vad som tillämpas.
  2. Kör terraform tillämpa för att tillämpa körningsplanen.

    terraform apply main.destroy.tfplan
    

Felsöka Terraform i Azure

Felsöka vanliga problem när du använder Terraform i Azure

Nästa steg