Create a confidential compute avd session host with Terraform Part 1

Hi everybody,

In July from this year Microsoft announced the general availability from confidential virtual machines for Azure Virtual Desktop. You can read the announcement here.

With the possibility of using confidential compute for your session hosts, we can increase the security of our environment.

I’ve split up this blog post in 2 parts. This part will discuss the deployment of the Key Vault, Key Vault Key and the Disk Encryption Set that we will use for the virtual machine deployment. In part 2 I’ll show how to deploy an AVD session host on confidential compute hardware with Terraform.

RBAC role creation

Before we start creating our Key Vault resources we need to grant the confidential VM Service Principal access to our tenant. This is done using the Cloudshell and with the following command.

Connect-AzureAD -Tenant "your tenant ID"
New-AzureADServicePrincipal -AppId bf7b6499-ff71-4aa2-97a4-f372087be7f0 -DisplayName "Confidential VM Orchestrator"

The first resource that we need is the Azure Key Vault. There are a couple of things to know about this kind of Key Vault that is needed for confidential compute.

  • Key Vault Premium Sku
  • Purge Protection enabled

Key Vault deployment

The first piece of code that we need is that for the Key Vault. I’m deploying it in a management resource group for AVD.

resource "azurerm_key_vault" "kv" {
  provider = azurerm.hub
  depends_on = [ data.azurerm_resource_group.rg-kv ]
  name                        = "kv-${var.env}-${var.prefix}-${var.solution}-80"
  location                    = data.azurerm_resource_group.rg-kv.location
  resource_group_name         =
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days  = 7
  purge_protection_enabled    = true #be careful with this feature
  enabled_for_deployment = true
  enabled_for_template_deployment = true
  enabled_for_disk_encryption = true
  public_network_access_enabled = false
  sku_name = "premium"
  tags = {
    "Costcenter"   = "ICT"
    "Critical"     = "Yes"
    "Environment"  = "AVD PRD"
    "Solution"     = "Keyvault"

Very important that we also enable the diagnostic settings for the Key Vault.

resource "azurerm_monitor_diagnostic_setting" "kv-diag" {
  name               = "diag-keyvault"
  target_resource_id =
  log_analytics_workspace_id =
  log {
    category = "AuditEvent"
    enabled  = true

    retention_policy {
      enabled = true
  log {
    category = "AzurePolicyEvaluationDetails"
    enabled  = true

    retention_policy {
      enabled = true

  metric {
    category = "AllMetrics"

    retention_policy {
      enabled = true

Azure Key Vault Key

The second resource that we need is the Key Vault key. Since it needs a specific setting for confidential compute that is not available with Terraform, I show the creation in the portal. It’s very important to use the CVM confidential operation policy.

When created you can also check the properties of the key.

Disk Encryption set

The final resource that we need is the Disk Encryption set. First we import the already created key.

data "azurerm_key_vault_key" "avd-key" {
  name = "key-prd-jvn-avd-10"
  key_vault_id =
resource "azurerm_disk_encryption_set" "en-set" {
    provider = azurerm.hub
  name                = "des-${var.env}-${var.prefix}-avd-50"
  resource_group_name =
  location            = data.azurerm_resource_group.rg-kv.location
  key_vault_key_id    =
  encryption_type = "ConfidentialVmEncryptedWithCustomerKey"

  identity {
    type = "SystemAssigned"

When deployed we can check the encryption type of the disk encryption set os for confidential compute.

Access policies Key Vault

Now that we have all the resources, let us also look at all the access policies on the Key Vault because this is very important if you want to be able to deploy confidential machines.

You can see the policy for the Confidential VM Orchestrator and the policy for the Disk Encryption Set. If these access policies are not in place, the session hosts will be created but won’t be able to start and it will be in a stopped state.

Now that we have all these resources deployed we can start deploying our new session hosts on Confidential Compute Hardware. Stay tuned to part 2 where I show how to do this.

The full Terraform script is on my Github here.

In case you have questions about this part or something isn’t clear, feel free to contact me by leaving a comment or on my socials.

2 thoughts on “Create a confidential compute avd session host with Terraform Part 1

Leave a Reply

Your email address will not be published. Required fields are marked *