hashicorp / terraform-provider-azurerm

Terraform provider for Azure Resource Manager
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs
Mozilla Public License 2.0
4.51k stars 4.6k forks source link

Azure Disk Encryption Extension not Deploying to VM #25152

Open Krisnov27614 opened 6 months ago

Krisnov27614 commented 6 months ago

Is there an existing issue for this?

Community Note

Terraform Version

1.7.4

AzureRM Provider Version

3.94.0

Affected Resource(s)/Data Source(s)

azurerm_virtual_machine_extension

Terraform Configuration Files

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.94.0"
    }

    azuread = {
      source = "hashicorp/azuread"
    }
  }
}

provider "azurerm" {
   features{}

data "azuread_user" "Admin_User" {
    user_principal_name = var.Admin_User
}

resource "azurerm_resource_group" "rg" {
    location = var.sitelocation
    name     = "${var.Site_Prefix}-rg"
}

resource "azurerm_virtual_network" "vnet" {
    name                = "${var.Site_Prefix}-vnet"
    location            = var.sitelocation
    address_space       = var.vnet_address_space
    resource_group_name = azurerm_resource_group.rg.name

    depends_on = [
        azurerm_resource_group.rg 
    ]
}

resource "azurerm_subnet" "VM_Subnet" {
    name                 = "${var.Site_Prefix}-sub"
    resource_group_name  = azurerm_resource_group.rg.name
    virtual_network_name = azurerm_virtual_network.vnet.name
    address_prefixes     = var.vm_subnet_prefix

    depends_on = [ 
        azurerm_virtual_network.vnet 
    ]
}

resource "azurerm_network_interface" "VM_NIC" {
    name                = "Prod-Nic"
    location            = var.sitelocation
    resource_group_name = azurerm_resource_group.rg.name

    ip_configuration {
      name                          = "Prod-Public-IP"
      subnet_id                     = azurerm_subnet.VM_Subnet.id
      private_ip_address_allocation = "Dynamic"

      public_ip_address_id          = azurerm_public_ip.Prod_Public.id
    }

    depends_on = [ 
        azurerm_subnet.VM_Subnet 
    ]
}

resource "azurerm_public_ip" "Prod_Public" {
    name                = "Prod-Public"
    resource_group_name = azurerm_resource_group.rg.name
    location            = var.sitelocation
    allocation_method   = "Static"
}

resource "azurerm_storage_account" "Storage_Account" {
    name                     = "${var.Site_Prefix}diag${var.Customer_Number}"
    resource_group_name      = azurerm_resource_group.rg.name
    location                 = var.sitelocation
    account_tier             = "Standard"
    account_replication_type = "LRS"
}

 resource "azurerm_virtual_machine" "Prod" {
    name                  = "Prod-${var.Site_Prefix}-${var.Customer_Number}"
    location              = var.sitelocation
    resource_group_name   = azurerm_resource_group.rg.name
    network_interface_ids = [azurerm_network_interface.VM_NIC.id]
    vm_size               = var.VM_Size

    boot_diagnostics {
      enabled     = true
      storage_uri = "${azurerm_storage_account.Storage_Account.primary_blob_endpoint}"
    }

    storage_image_reference {
        id = "${data.azurerm_shared_image.image.id}"
    }

    storage_os_disk {
        create_option = "FromImage"
        name          = "Prod-OS"
        os_type = "Windows"
        managed_disk_type = "Standard_LRS"
    }

   storage_data_disk {
      create_option = "FromImage"
      name = "Prod-Data"
      lun = "0"
    }

    depends_on = [ 
        azurerm_network_interface.VM_NIC,
        azurerm_storage_account.Storage_Account
    ]
} 
resource "azurerm_key_vault" "Key_Vault" {
    name                        = "${var.Site_Prefix}vault${var.Customer_Number}"
    location                    = var.sitelocation
    resource_group_name         = azurerm_resource_group.rg.name
    tenant_id                   = data.azurerm_client_config.current.tenant_id
    sku_name                    = "standard"
    enabled_for_disk_encryption = true
    purge_protection_enabled    = true
    enabled_for_deployment      = true
}

resource "azurerm_key_vault_access_policy" "SP_Access" {
    key_vault_id = azurerm_key_vault.Key_Vault.id
    tenant_id    = data.azurerm_client_config.current.tenant_id
    object_id    = data.azuread_user.Admin_User.object_id

    key_permissions = [
        "Create",
        "Delete",
        "Get",
        "Purge",
        "Recover",
        "Update",
        "List",
        "Decrypt",
        "Sign",
        "Import",
        "Backup",
        "Restore",
        "Encrypt",
        "WrapKey",
        "UnwrapKey",
        "GetRotationPolicy",
        "SetRotationPolicy"
    ]

    secret_permissions = [
        "Get",
        "List",
        "Set",
        "Delete",
        "Recover",
        "Backup",
        "Restore",
        "Purge"
    ]

    depends_on = [ data.azurerm_client_config.current ]
}

resource "azurerm_key_vault_key" "ADE_Key" {
    name         = "${var.Site_Prefix}-key${var.Customer_Number}"
    key_vault_id = azurerm_key_vault.Key_Vault.id
    key_type     = "RSA"
    key_size     = 4096

     key_opts = [
        "decrypt",
        "encrypt",
        "sign",
        "unwrapKey",
        "verify",
        "wrapKey",
     ]

     depends_on = [ 
        azurerm_key_vault_access_policy.SP_Access,
      ]
}

resource "azurerm_virtual_machine_extension" "Deploy_ADE" {
    provider = azurerm
    name                       = "AzureDiskEncryption"
    virtual_machine_id         = azurerm_virtual_machine.Prod.id
    publisher                  = "Microsoft.Azure.Security"
    type                       = "AzureDiskEncryption"
    type_handler_version       = "2.2"
    auto_upgrade_minor_version = true

    settings = jsonencode({
        AADClientCertThumbprint =""
        AADClientID = ""
        KekVaultResourceID = ""
        KeyEncryptionAlgorithm = ""
        SequenceVersion =""

        EncryptionOperation    = "EnableEncryption"
        KeyVaultResourceId     =****Resource ID Entered Here****
        KeyVaultURL            = "****URL Entered Here*****
        KeyEncryptionKeyURL    = *****Key URL Entered Here*****
        VolumeType             = "All"
    })

    depends_on = [ azurerm_key_vault_access_policy.SP_Access ]
}

Debug Output/Panic Output

Error: Code="VMExtensionProvisioningError" Message="VM has reported a failure when processing extension 'AzureDiskEncryption' (publisher 'Microsoft.Azure.Security' and type 'AzureDiskEncryption'). Error message: '[2.4.0.21] Failed to configure bitlocker as expected. Exception: Value cannot be null.\r\nParameter name: resIdString, InnerException: , stack trace:    at Microsoft.Cis.Security.BitLocker.BitlockerIaasVMExtension.Settings.BitlockerExtensionSettings.ValidateKeyVaultResourceId(String resIdString) in C:\\__w\\1\\s\\src\\BitLocker\\BitlockerIaasVMExtension\\Settings\\BitlockerExtensionSettings.cs:line 151\r\n   at Microsoft.Cis.Security.BitLocker.BitlockerIaasVMExtension.Settings.BitlockerExtensionSettings.GetExtensionPublicSettings(IVMSecurityProfileDetails vmSecProfileDetails) in C:\\__w\\1\\s\\src\\BitLocker\\BitlockerIaasVMExtension\\Settings\\BitlockerExtensionSettings.cs:line 250\r\n   at Microsoft.Cis.Security.BitLocker.BitlockerIaasVMExtension.BitlockerExtension.InitializeExtension(ILogger logger) in C:\\__w\\1\\s\\src\\BitLocker\\BitlockerIaasVMExtension\\BitlockerExtension.cs:line 2198\r\n   at Microsoft.Cis.Security.BitLocker.BitlockerIaasVMExtension.BitlockerExtension.OnEnable() in C:\\__w\\1\\s\\src\\BitLocker\\BitlockerIaasVMExtension\\BitlockerExtension.cs:line 2282'. More information on troubleshooting is available at https://aka.ms/VMExtensionADEWindowsTroubleshoot. "
│
│   with azurerm_virtual_machine_extension.Deploy_ADE,
│   on main.tf line 411, in resource "azurerm_virtual_machine_extension" "Deploy_ADE":
│  411:   resource "azurerm_virtual_machine_extension" "Deploy_ADE" {
│

Expected Behaviour

Deploy Azure Windows VM from Image and deploy Azure Disk Encryption via Extension

Actual Behaviour

Extension errors out because of a missing variable "resIDString" which seems to map to the Key Vault Resource ID which is provided. ADE is not applied Disk Encryption Error

Steps to Reproduce

terraform apply

Important Factoids

No response

References

No response

ms-zhenhua commented 6 months ago

Hi @Krisnov27614, thank you for reaching out. This error is returned by Azure, not the provider. From the error log, it seems that the issue is caused by some properties that are not defined or defined as an empty value. You may refer to the following configuration which is similar with yours and can successfully deploy the AzureDiskEncryption extension. If it cannot solve your problem, you may reach out to Azure support and report an API error(azurerm_virtual_machine_extension underlyingly uses Virtual Machine Extensions API).

provider "azurerm" {
  features {}
}

locals {
  Site_Prefix        = "acctest"
  Customer_Number    = "1234"
  sitelocation       = "westeurope"
  vnet_address_space = ["10.0.0.0/16"]
  vm_subnet_prefix   = ["10.0.2.0/24"]
  VM_Size            = "Standard_D2s_v3"
}

data "azurerm_client_config" "current" {}

resource "azurerm_resource_group" "rg" {
  location = local.sitelocation
  name     = "${local.Site_Prefix}-rg"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "${local.Site_Prefix}-vnet"
  location            = local.sitelocation
  address_space       = local.vnet_address_space
  resource_group_name = azurerm_resource_group.rg.name

  depends_on = [
    azurerm_resource_group.rg
  ]
}

resource "azurerm_subnet" "VM_Subnet" {
  name                 = "${local.Site_Prefix}-sub"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = local.vm_subnet_prefix

  depends_on = [
    azurerm_virtual_network.vnet
  ]
}

resource "azurerm_network_interface" "VM_NIC" {
  name                = "Prod-Nic"
  location            = local.sitelocation
  resource_group_name = azurerm_resource_group.rg.name

  ip_configuration {
    name                          = "Prod-Public-IP"
    subnet_id                     = azurerm_subnet.VM_Subnet.id
    private_ip_address_allocation = "Dynamic"

    public_ip_address_id = azurerm_public_ip.Prod_Public.id
  }

  depends_on = [
    azurerm_subnet.VM_Subnet
  ]
}

resource "azurerm_public_ip" "Prod_Public" {
  name                = "Prod-Public"
  resource_group_name = azurerm_resource_group.rg.name
  location            = local.sitelocation
  allocation_method   = "Static"
}

resource "azurerm_windows_virtual_machine" "Prod" {
  name                = "${local.Site_Prefix}-${local.Customer_Number}"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  size                = "Standard_D2s_v3"
  admin_username      = "adminuser"
  admin_password      = "***********"
  network_interface_ids = [
    azurerm_network_interface.VM_NIC.id,
  ]

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2022-Datacenter"
    version   = "latest"
  }

  os_disk {
    storage_account_type = "Standard_LRS"
    caching              = "ReadWrite"
  }
}

resource "azurerm_key_vault" "Key_Vault" {
  name                        = "${local.Site_Prefix}vault${local.Customer_Number}"
  location                    = local.sitelocation
  resource_group_name         = azurerm_resource_group.rg.name
  tenant_id                   = data.azurerm_client_config.current.tenant_id
  sku_name                    = "standard"
  enabled_for_disk_encryption = true
  purge_protection_enabled    = true
  enabled_for_deployment      = true
}

resource "azurerm_key_vault_access_policy" "SP_Access" {
  key_vault_id = azurerm_key_vault.Key_Vault.id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = data.azurerm_client_config.current.object_id

  key_permissions = [
    "Create",
    "Delete",
    "Get",
    "Purge",
    "Recover",
    "Update",
    "List",
    "Decrypt",
    "Sign",
    "Import",
    "Backup",
    "Restore",
    "Encrypt",
    "WrapKey",
    "UnwrapKey",
    "GetRotationPolicy",
    "SetRotationPolicy"
  ]

  secret_permissions = [
    "Get",
    "List",
    "Set",
    "Delete",
    "Recover",
    "Backup",
    "Restore",
    "Purge"
  ]

  depends_on = [data.azurerm_client_config.current]
}

resource "azurerm_key_vault_key" "ADE_Key" {
  name         = "${local.Site_Prefix}-key${local.Customer_Number}"
  key_vault_id = azurerm_key_vault.Key_Vault.id
  key_type     = "RSA"
  key_size     = 4096

  key_opts = [
    "decrypt",
    "encrypt",
    "sign",
    "unwrapKey",
    "verify",
    "wrapKey",
  ]

  depends_on = [
    azurerm_key_vault_access_policy.SP_Access,
  ]
}

resource "azurerm_virtual_machine_extension" "Deploy_ADE" {
  name                       = "AzureDiskEncryption"
  virtual_machine_id         = azurerm_windows_virtual_machine.Prod.id
  publisher                  = "Microsoft.Azure.Security"
  type                       = "AzureDiskEncryption"
  type_handler_version       = "2.2"
  auto_upgrade_minor_version = true

  settings = <<SETTINGS
{
  "EncryptionOperation": "EnableEncryption",
  "KeyEncryptionAlgorithm": "RSA-OAEP",
  "KeyVaultURL": "${azurerm_key_vault.Key_Vault.vault_uri}",
  "KeyVaultResourceId": "${azurerm_key_vault.Key_Vault.id}",
  "KeyEncryptionKeyURL": "${azurerm_key_vault_key.ADE_Key.id}",
  "KekVaultResourceId": "${azurerm_key_vault.Key_Vault.id}",
  "VolumeType": "All"
}
SETTINGS
}

image