Azure Virtual Desktop with Terraform – Pooled, Personal, RemoteApp + Monitoring, Dashboards and Scaling – All-in-one

16 Mar

During Workplace Ninja US, I did an in-person session on this topic, and now I am releasing for all. I’ve built Azure Virtual Desktop environments in a few different ways over the years — quick POCs, “just one host pool” builds, and full-blown enterprise deployments. The problem is the same every time: it starts simple and then you end up stitching together monitoring, scaling plans, RBAC, dashboards, and cost alerts… usually across multiple Terraform folders.

So I pulled everything into one modular Terraform repo that can deploy four AVD patterns (pooled/personal + desktop/RemoteApp), with optional enterprise-grade monitoring, dashboards, cost management, and scaling.

Repo – askaresh/avd_terraform: Azure Virtual Desktop and Terraform. Everything you need in a single repo!

What we are building

This repo deploys a complete AVD environment and supports four deployment types:

  • pooled_desktop (shared desktops)
  • personal_desktop (dedicated 1:1 desktops)
  • pooled_remoteapp (published apps, shared hosts)
  • personal_remoteapp (published apps, dedicated hosts)

It also follows Microsoft Cloud Adoption Framework (CAF) naming patterns for the main AVD + network resources (host pool, app group, workspace, vnet/subnet/nsg, etc.).

Why this repo is “enterprise ready”

A few highlights that make this more than a basic host pool deployment:

  • Scaling plans for pooled deployments (desktop + RemoteApp) and environment-specific schedules
  • Monitoring & observability using Log Analytics + diagnostics
  • Custom dashboards for operational visibility
  • Cost management with budgets + alerts
  • CAF-friendly naming so your portal stays clean and consistent

Supported deployment types (quick view)

The configuration automatically adjusts host pool/app group settings depending on deployment_type (pooled vs personal, desktop vs RemoteApp).

Deployment typeHost pool typeApp group typeNotes
pooled_desktopPooledDesktopScaling supported
personal_desktopPersonalDesktopStart VM on connect behavior differs
pooled_remoteappPooledRemoteAppScaling supported
personal_remoteappPersonalRemoteAppDedicated apps per user

Pre-requisites

  • Terraform + required providers (azurerm/azuread/random/azapi)
  • An Azure subscription with AVD enabled
  • Object IDs for users/groups/service principals that should be granted access (security_principal_object_ids)

Session host default image SKU in the repo is Windows 11 multi-session + M365 (win11-24h2-avd-m365).

Deployment steps (what I run)

Clone the repo

git clone https://github.com/askaresh/avd_terraform
cd avd_terraform

Pick a deployment file (.tfvars)

The repo includes pre-configured examples for different deployment types (dev/prod, pooled/personal, desktop/RemoteApp), plus enhanced options.

Examples:

  • dev-pooled-desktop.tfvars
  • dev-personal-desktop.tfvars
  • dev-pooled-remoteapp.tfvars
  • prod-personal-remoteapp.tfvars
  • dev-pooled-desktop-enhanced-scaling.tfvars

Update the must-have variables

At minimum, set:

  • security_principal_object_ids (who gets access)
  • admin_password (local admin password for session hosts)

RemoteApp tip: for RemoteApp deployment types, you’ll also define published_applications (apps to publish).

<!-- INSERT SCREENSHOT: tfvars edits (redact secrets) -->

Authentication (repo way: .env + set-auth.ps1)

The deployment guide uses a Service Principal stored in a local .env file (ignored by git), and a set-auth.ps1 script that loads the values into ARM_* environment variables for Terraform.

High level flow:
.envset-auth.ps1ARM_* env vars → Terraform

Create your .env from .env.example, then run:

.\set-auth.ps1

Scaling plans note: your Service Principal needs the Desktop Virtualization Power On Off Contributor role at subscription scope for scaling to work properly.

Terraform init / plan / apply

terraform init
terraform plan -var-file=dev-pooled-desktop.tfvars
terraform apply -var-file=dev-pooled-desktop.tfvars

Monitoring, dashboards, cost alerts (optional but worth it)

If you use one of the monitoring/scaling-enabled tfvars options, the repo can deploy:

  • Log Analytics + diagnostics
  • Dashboards for ops visibility
  • Budgets/alerts for cost tracking

A quick note on dependency ordering (why it matters)

The repo is intentional about resource ordering — especially for scaling plans — to avoid portal oddities and ensure the host pool association is reliable. The dependency flow is documented and includes a separate scaling plan host pool association resource.

Resoure Group (RG)

Application Groups (AG)

Wrap up

If you want a repeatable way to deploy AVD that supports pooled + personal and desktop + RemoteApp, while also giving you the option to turn on monitoring, dashboards, budgets/alerts, and scaling, this repo is designed for exactly that.

Thanks,
Aresh Sarkari

Leave a Reply

Discover more from AskAresh

Subscribe now to keep reading and get access to the full archive.

Continue reading