Skip to content

claranet/terraform-azurerm-avd

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Virtual Desktop

Changelog Notice Apache V2 License OpenTofu Registry

Terraform module to deploy an Azure Virtual Desktop.

Global versioning rule for Claranet Azure modules

Module version Terraform version OpenTofu version AzureRM version
>= 8.x.x Unverified 1.8.x >= 4.0
>= 7.x.x 1.3.x >= 3.0
>= 6.x.x 1.x >= 3.0
>= 5.x.x 0.15.x >= 2.0
>= 4.x.x 0.13.x / 0.14.x >= 2.0
>= 3.x.x 0.12.x >= 2.0
>= 2.x.x 0.12.x < 2.0
< 2.x.x 0.11.x < 2.0

Contributing

If you want to contribute to this repository, feel free to use our pre-commit git hook configuration which will help you automatically update and format some files for you by enforcing our Terraform code module best-practices.

More details are available in the CONTRIBUTING.md file.

Usage

This module is optimized to work with the Claranet terraform-wrapper tool which set some terraform variables in the environment needed by this module. More details about variables set by the terraform-wrapper available in the documentation.

⚠️ Since modules version v8.0.0, we do not maintain/check anymore the compatibility with Hashicorp Terraform. Instead, we recommend to use OpenTofu.

locals {
  timezone = "Romance Standard Time"

  # Entra ID
  avd_group_display_name = "AVD Users"
  avd_user_01_object_id  = "axxxxxxx-axxx-axxx-axxx-axxxxxxxxxxx"
  avd_user_02_object_id  = "bxxxxxxx-bxxx-bxxx-bxxx-bxxxxxxxxxxx"
}

data "azuread_group" "avd_group" {
  display_name     = local.avd_group_display_name
  security_enabled = true
}

module "avd" {
  source  = "claranet/avd/azurerm"
  version = "x.x.x"

  location       = module.azure_region.location
  location_short = module.azure_region.location_short
  client_name    = var.client_name
  environment    = var.environment
  stack          = var.stack

  resource_group_name = module.rg.name

  workspace_config = {
    extra_tags = {
      foo = "bar"
    }
  }

  host_pool_config = {
    load_balancer_type       = "DepthFirst" # Value will automatically change depending on the Scaling Plan settings
    maximum_sessions_allowed = 24
    scheduled_agent_updates = {
      enabled  = true
      timezone = local.timezone
      schedules = [
        {
          day_of_week = "Sunday"
          hour_of_day = 8
        },
        {
          day_of_week = "Wednesday"
          hour_of_day = 22
        },
      ]
    }
  }

  application_group_config = {
    role_assignments_object_ids = concat(
      data.azuread_group.avd_group.members,
      [
        local.avd_user_01_object_id,
        local.avd_user_02_object_id,
      ],
    )
  }

  applications_config = {
    app-1 = {
      path = "C:\\application\\app-1.exe"
    }
  }

  scaling_plan_config = {
    enabled  = true
    timezone = local.timezone
    schedules = [
      {
        name                 = "weekdays"
        days_of_week         = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"]
        ramp_up_start_time   = "08:00"
        peak_start_time      = "09:00"
        ramp_down_start_time = "19:00"
        off_peak_start_time  = "22:00"
      },
      {
        name                 = "weekend"
        days_of_week         = ["Saturday", "Sunday"]
        ramp_up_start_time   = "09:00"
        peak_start_time      = "10:00"
        ramp_down_start_time = "17:00"
        off_peak_start_time  = "20:00"
      },
    ]
    # role_assignment = {
    #   enabled   = false                                   # `false` if you do not have permission to create the Role and the Role Assignment, but this must be done somehow
    #   object_id = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee" # In case you do not have permsision to retrieve the object ID of the AVD Service Principal
    # }
  }

  logs_destinations_ids = [
    module.run.logs_storage_account_id,
    module.run.log_analytics_workspace_id,
  ]

  extra_tags = {
    purpose = "demo"
  }
}

Providers

Name Version
azuread ~> 3.0
azurecaf ~> 1.2.28
azurerm ~> 4.0
time ~> 0.12

Modules

Name Source Version
diagnostics_app_group claranet/diagnostic-settings/azurerm ~> 8.0.0
diagnostics_host_pool claranet/diagnostic-settings/azurerm ~> 8.0.0
diagnostics_scaling_plan claranet/diagnostic-settings/azurerm ~> 8.0.0
diagnostics_workspace claranet/diagnostic-settings/azurerm ~> 8.0.0

Resources

Name Type
azurerm_role_assignment.app_group_role_assignments resource
azurerm_role_assignment.scaling_role_assignment resource
azurerm_role_definition.scaling_role_definition resource
azurerm_virtual_desktop_application.main resource
azurerm_virtual_desktop_application_group.main resource
azurerm_virtual_desktop_host_pool.main resource
azurerm_virtual_desktop_host_pool_registration_info.main resource
azurerm_virtual_desktop_scaling_plan.main resource
azurerm_virtual_desktop_workspace.main resource
azurerm_virtual_desktop_workspace_application_group_association.main resource
time_rotating.time resource
azuread_application_published_app_ids.well_known data source
azuread_service_principal.avd_service_principal data source
azurecaf_name.avd_app data source
azurecaf_name.avd_app_group data source
azurecaf_name.avd_host_pool data source
azurecaf_name.avd_scaling_plan data source
azurecaf_name.avd_workspace data source
azurerm_client_config.current data source

Inputs

Name Description Type Default Required
application_group_config AVD Application Group specific configuration.
object({
friendly_name = optional(string)
default_desktop_display_name = optional(string)
description = optional(string)
type = optional(string, "Desktop")
role_assignments_object_ids = optional(list(string), [])
extra_tags = optional(map(string))
})
{} no
application_group_custom_name Custom Azure Virtual Desktop Application Group name, generated if not set. string "" no
applications_config AVD applications configuration. Description of parameters here.
map(object({
custom_name = optional(string)
friendly_name = optional(string)
description = optional(string)
path = string
command_line_argument_policy = optional(string, "DoNotAllow")
command_line_arguments = optional(string)
show_in_portal = optional(bool)
icon_path = optional(string)
icon_index = optional(string)
}))
{} no
client_name Client name/account used in naming. string n/a yes
default_tags_enabled Option to enable or disable default tags. bool true no
diagnostic_settings_custom_name Custom name of the diagnostics settings, name will be default if not set. string "default" no
environment Project environment. string n/a yes
extra_tags Additional tags to add on resources. map(string) {} no
host_pool_config AVD Host Pool specific configuration.
object({
friendly_name = optional(string)
description = optional(string)
validate_environment = optional(bool, true)
custom_rdp_properties = optional(string, "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;use multimon:i:1;")
public_network_access = optional(string, "Enabled")
type = optional(string, "Pooled")
load_balancer_type = optional(string, "BreadthFirst")
personal_desktop_assignment_type = optional(string, "Automatic")
maximum_sessions_allowed = optional(number, 16)
preferred_app_group_type = optional(string)
start_vm_on_connect = optional(bool, false)
host_registration_expires_in_in_hours = optional(number, 48)
scheduled_agent_updates = optional(object({
enabled = optional(bool, false)
timezone = optional(string, "UTC") # https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/
use_session_host_timezone = optional(bool, false)
schedules = optional(list(object({
day_of_week = string
hour_of_day = number
})), [])
}), {})
extra_tags = optional(map(string))
})
{} no
host_pool_custom_name Custom Azure Virtual Desktop host pool name, generated if not set. string "" no
location Azure region to use. string n/a yes
location_short Short string for Azure location. string n/a yes
logs_categories Log categories to send to destinations. list(string) null no
logs_destinations_ids List of destination resources IDs for logs diagnostic destination.
Can be Storage Account, Log Analytics Workspace and Event Hub. No more than one of each can be set.
If you want to use Azure EventHub as a destination, you must provide a formatted string containing both the EventHub Namespace authorization send ID and the EventHub name (name of the queue to use in the Namespace) separated by the | character.
list(string) n/a yes
logs_metrics_categories Metrics categories to send to destinations. list(string) null no
name_prefix Optional prefix for the generated name. string "" no
name_suffix Optional suffix for the generated name. string "" no
resource_group_name Name of the resource group. string n/a yes
scaling_plan_config AVD Scaling Plan specific configuration.
object({
enabled = optional(bool, false)
friendly_name = optional(string)
description = optional(string)
exclusion_tag = optional(string)
timezone = optional(string, "UTC") # https://jackstromberg.com/2017/01/list-of-time-zones-consumed-by-azure/
schedules = optional(list(object({
name = string
days_of_week = list(string)
peak_start_time = string
peak_load_balancing_algorithm = optional(string, "BreadthFirst")
off_peak_start_time = string
off_peak_load_balancing_algorithm = optional(string, "DepthFirst")
ramp_up_start_time = string
ramp_up_load_balancing_algorithm = optional(string, "BreadthFirst")
ramp_up_capacity_threshold_percent = optional(number, 75)
ramp_up_minimum_hosts_percent = optional(number, 33)
ramp_down_start_time = string
ramp_down_capacity_threshold_percent = optional(number, 5)
ramp_down_force_logoff_users = optional(string, false)
ramp_down_load_balancing_algorithm = optional(string, "DepthFirst")
ramp_down_minimum_hosts_percent = optional(number, 33)
ramp_down_notification_message = optional(string, "Please log off in the next 45 minutes...")
ramp_down_stop_hosts_when = optional(string, "ZeroSessions")
ramp_down_wait_time_minutes = optional(number, 45)
})), [])
role_assignment = optional(object({
enabled = optional(bool, true)
object_id = optional(string)
}), {})
extra_tags = optional(map(string))
})
{} no
scaling_plan_custom_name Custom Azure Virtual Desktop Scaling Plan name, generated if not set. string "" no
stack Project stack name. string n/a yes
workspace_config AVD Workspace specific configuration.
object({
friendly_name = optional(string)
description = optional(string)
public_network_access_enabled = optional(bool)
extra_tags = optional(map(string))
})
{} no
workspace_custom_name Custom Azure Virtual Desktop workspace name, generated if not set. string "" no

Outputs

Name Description
application_group_id AVD Application Group ID.
application_group_name AVD Application Group name.
avd_service_principal_client_id AVD Service Principal Client ID (Application ID).
avd_service_principal_name AVD Service Principal name.
avd_service_principal_object_id AVD Service Principal Object ID (Principal ID).
host_pool_id AVD Host Pool ID.
host_pool_name AVD Host Pool name.
host_registration_token AVD host registration token.
host_registration_token_expiration_date AVD host registration token expiration date.
resouce_application AVD Application resource object.
resource_application_group AVD Application Group resource object.
resource_host_pool AVD Host Pool resource object.
resource_scaling_plan AVD Scaling Plan resource object.
resource_workspace AVD Workspace resource object.
scaling_plan_id AVD Scaling Plan ID.
scaling_plan_name AVD Scaling Plan name.
scaling_plan_role_definition AVD Scaling Plan Role Definition resource object.
scaling_plan_role_definition_id AVD Scaling Plan Role Definition ID.
scaling_plan_role_definition_name AVD Scaling Plan Role Definition name.
workspace_id AVD Workspace ID.
workspace_name AVD Workspace name.