Skip to content

Add AzAPI provider sample code for Azure Virtual Desktop - #483

Open
Steven (stemaMSFT) wants to merge 17 commits into
masterfrom
azapi/batch-1
Open

Steven (stemaMSFT) wants to merge 17 commits into
masterfrom
azapi/batch-1

Conversation

@stemaMSFT

@stemaMSFT Steven (stemaMSFT) commented May 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add an AzAPI provider equivalent of the Azure Virtual Desktop Terraform quickstart for use by Microsoft Learn.

This PR is limited to one deployable quickstart, as required by the repository validation contract introduced in #501. The Cosmos DB + ACI and resource-group samples were split into #485 and removed from this branch.

Sample

Folder Resources API Versions
quickstart/101-azure-virtual-desktop-azapi/ Log Analytics, VNet, NSG, Shared Image Gallery, Storage, VMs, AVD workspace/app group 2023-09-01, 2024-01-01, 2022-03-03, 2023-05-01, 2024-03-01, 2024-04-03

Design decisions

  • Keep the resource group, RBAC, Azure AD resources, and AVD host pool on providers that support their required behavior.
  • Use AzAPI v2 native HCL bodies.
  • Make external Active Directory integration optional so the standalone sample can validate without pre-existing AD infrastructure.
  • Retry known transient Azure deletion and capacity failures.
  • Configure AzureAD explicitly and skip automatic AzureRM provider registration for contributor contexts without registration permissions.

Local validation

  • terraform fmt -check -recursive quickstart/101-azure-virtual-desktop-azapi
  • terraform init -backend=false -input=false
  • terraform validate
  • Quickstart metadata validator unit tests
  • ARM correlation validator unit tests
  • Fresh successful metadata.json deployment evidence

Live validation blocker

A correlated apply was attempted with correlation ID 5ec2cc4d-44d4-484e-a6e4-38b235c25f0a starting at 2026-11-11T22:47:31Z. The configured Terraform validation subscription denied the deployment through explicit Azure Policy assignments:

  • management-group policy Block WVD creation (aka.ms/avdblock) denied Microsoft.DesktopVirtualization/* resources;
  • subscription policy Subnets should be private denied the sample VNet/subnet shape;
  • subscription policy Deny Storage Account Creation with Local Authentication denied the storage account.

All 10 partially created resources were destroyed, and all four test resource groups were verified absent. No metadata.json is committed because the apply did not succeed.

Linked documentation

  • MicrosoftDocs/azure-dev-docs-pr#9011

Steven (stemaMSFT) and others added 3 commits May 6, 2026 14:50
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove jsondecode() wrappers (azapi v2.0+ returns native objects)
- Use azapi_resource_action for Cosmos DB listKeys
- Consolidate duplicate resource group in AVD sample
- Remove dead random_string.rando code
- Fix past-date default in rfc3339 variable

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- AVD: Add default value for rfc3339 variable so terraform plan
  works without -var flags (required by Terratest CI)
- Cosmos ACI: Replace azure-vote-front:cosmosdb with aci-helloworld
  (the :cosmosdb tag was removed from MCR, also broken in upstream)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AVD:
- Make AD-dependent resources (VNet peering, RBAC) conditional via
  enable_ad_integration variable (default: false). CI environment
  lacks pre-existing AD infrastructure (same limitation as original
  azurerm sample).
- Add lifecycle ignore_changes on azapi_update_resource blocks to
  pass the Terratest idempotent plan check.

Cosmos DB + ACI:
- Add ignore_body_changes on Cosmos DB and ACI resources to handle
  API response normalization that causes plan drift.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Make storage RBAC role assignment conditional (afstorage.tf)
- Make domain_join extension conditional on enable_ad_integration
- Fix output for AVD_user_groupname with conditional index
- Add ignore_body_changes to VNet (subnet drift from nsg_assoc)
- Add ignore_body_changes to NIC (allocated IP), VM (adminPassword,
  osDisk, networkProfile), extensions (protectedSettings)
- Add ignore_body_changes for ACI ipAddress drift
- Remove stale depends_on from domain_join/vmext_dsc

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ignore_body_changes was removed in recent AzAPI versions. Use the
universal Terraform lifecycle { ignore_changes = [body] } instead,
which works across all provider versions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azure refuses to delete the NSG while NICs still reference the
associated subnet. Adding depends_on ensures destroy order:
VMs -> NICs -> nsg_assoc -> NSG -> VNet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
AzAPI provider lacks the built-in retry logic that azurerm has for
NicReservedForAnotherVm (180s platform lock after VM deletion).
With 2 VMs, parallel NIC deletions both hit the reservation.
Using 1 VM avoids the race while still demonstrating the pattern.

Also fixes gallery destroy ordering (image before gallery via parent_id).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- NIC: retry on NicReservedForAnotherVm (180s Azure platform lock)
- NSG: retry on InUseNetworkSecurityGroupCannotBeDeleted
- Gallery: retry on CannotDeleteResource
- Revert rdsh_count from 1 back to 2 (retry handles the race)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…10-22h2-avd

The 20h2-evd multi-session image has been removed from Azure Marketplace.
Updated to win10-22h2-avd (Windows 10 22H2 multi-session) which is the
current supported SKU for AVD deployments.

Also updated SIG image definition to use win10-22h2-avd-m365.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- VM size: Standard_DS2_v2 -> Standard_D2s_v5 (capacity-constrained in eastus)
- Registration token: use timeadd(timestamp(), '23h') instead of
  hardcoded 2099 date that exceeds the 30-day max window

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CI subscription has 0 quota for DSv5 family. Revert VM size to
Standard_DS2_v2 (DSv2 family has quota). Add retry block on VM
resource for transient SkuNotAvailable/capacity errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the Cosmos DB + ACI and resource-group samples now owned by the split PR, and apply canonical Terraform formatting after merging master.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@stevenjma Steven Ma (stevenjma) changed the title Add AzAPI provider sample code for AVD and Cosmos DB articles Add AzAPI provider sample code for Azure Virtual Desktop Nov 11, 2026
Configure the declared AzureAD provider and disable automatic AzureRM resource provider registration so contributor contexts without registration permissions can plan the sample.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

This branch had an error being deployed

1 failed (outdated) deployment
test — 73ccf041 Deployed May 8, 2026 by stemaMSFT via e2e-check #881
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants