diff --git a/azurerm/internal/services/compute/linux_virtual_machine_resource.go b/azurerm/internal/services/compute/linux_virtual_machine_resource.go index 5c155ca2c4f2a..deef305808a4a 100644 --- a/azurerm/internal/services/compute/linux_virtual_machine_resource.go +++ b/azurerm/internal/services/compute/linux_virtual_machine_resource.go @@ -887,7 +887,7 @@ func resourceLinuxVirtualMachineUpdate(d *schema.ResourceData, meta interface{}) } if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting to update encryption settings of of OS Disk %q for Linux Virtual Machine %q (Resource Group %q): %+v", diskName, id.Name, id.ResourceGroup, err) + return fmt.Errorf("Error waiting to update encryption settings of OS Disk %q for Linux Virtual Machine %q (Resource Group %q): %+v", diskName, id.Name, id.ResourceGroup, err) } log.Printf("[DEBUG] Updating encryption settings of OS Disk %q for Linux Virtual Machine %q (Resource Group %q) to %q.", diskName, id.Name, id.ResourceGroup, diskEncryptionSetId) diff --git a/azurerm/internal/services/compute/tests/windows_virtual_machine_resource_disk_os_test.go b/azurerm/internal/services/compute/tests/windows_virtual_machine_resource_disk_os_test.go index 4558419c2f96b..cee4758a1a927 100644 --- a/azurerm/internal/services/compute/tests/windows_virtual_machine_resource_disk_os_test.go +++ b/azurerm/internal/services/compute/tests/windows_virtual_machine_resource_disk_os_test.go @@ -149,24 +149,38 @@ func TestAccWindowsVirtualMachine_diskOSDiskEncryptionSet(t *testing.T) { CheckDestroy: checkWindowsVirtualMachineIsDestroyed, Steps: []resource.TestStep{ { - // TODO: After applying soft-delete and purge-protection in keyVault, this extra step can be removed. - Config: testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetDependencies(data), + Config: testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetEncrypted(data), Check: resource.ComposeTestCheckFunc( - enableSoftDeleteAndPurgeProtectionForKeyVault("azurerm_key_vault.test"), + checkWindowsVirtualMachineExists(data.ResourceName), ), }, + data.ImportStep("admin_password"), + }, + }) +} + +func TestAccWindowsVirtualMachine_diskOSDiskEncryptionSetUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: checkWindowsVirtualMachineIsDestroyed, + Steps: []resource.TestStep{ { - Config: testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetResource(data), + Config: testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetUnencrypted(data), + Check: resource.ComposeTestCheckFunc( + checkWindowsVirtualMachineExists(data.ResourceName), + ), }, + data.ImportStep("admin_password"), { - Config: testWindowsVirtualMachine_diskOSDiskDiskEncryptionSet(data), + Config: testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetEncrypted(data), Check: resource.ComposeTestCheckFunc( checkWindowsVirtualMachineExists(data.ResourceName), ), }, - data.ImportStep( - "admin_password", - ), + data.ImportStep("admin_password"), }, }) } @@ -479,6 +493,10 @@ func testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetDependencies(data acce location := "westus2" return fmt.Sprintf(` +provider "azurerm" { + features {} +} + # note: whilst these aren't used in all tests, it saves us redefining these everywhere locals { vm_name = "acctestvm%s" @@ -497,6 +515,8 @@ resource "azurerm_key_vault" "test" { resource_group_name = azurerm_resource_group.test.name tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "premium" + soft_delete_enabled = true + purge_protection_enabled = true enabled_for_disk_encryption = true } @@ -602,7 +622,43 @@ resource "azurerm_role_assignment" "disk-encryption-read-keyvault" { `, template, data.RandomInteger) } -func testWindowsVirtualMachine_diskOSDiskDiskEncryptionSet(data acceptance.TestData) string { +func testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetUnencrypted(data acceptance.TestData) string { + template := testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetResource(data) + return fmt.Sprintf(` +%s + +resource "azurerm_windows_virtual_machine" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + size = "Standard_F2" + admin_username = "adminuser" + admin_password = "P@$$w0rd1234!" + network_interface_ids = [ + azurerm_network_interface.test.id, + ] + + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2016-Datacenter" + version = "latest" + } + + depends_on = [ + "azurerm_role_assignment.disk-encryption-read-keyvault", + "azurerm_key_vault_access_policy.disk-encryption", + ] +} +`, template) +} + +func testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetEncrypted(data acceptance.TestData) string { template := testWindowsVirtualMachine_diskOSDiskDiskEncryptionSetResource(data) return fmt.Sprintf(` %s @@ -620,8 +676,8 @@ resource "azurerm_windows_virtual_machine" "test" { os_disk { caching = "ReadWrite" - disk_encryption_set_id = azurerm_disk_encryption_set.test.id storage_account_type = "Standard_LRS" + disk_encryption_set_id = azurerm_disk_encryption_set.test.id } source_image_reference { diff --git a/azurerm/internal/services/compute/windows_virtual_machine_resource.go b/azurerm/internal/services/compute/windows_virtual_machine_resource.go index 58012d741865b..53b1348144f99 100644 --- a/azurerm/internal/services/compute/windows_virtual_machine_resource.go +++ b/azurerm/internal/services/compute/windows_virtual_machine_resource.go @@ -891,6 +891,37 @@ func resourceWindowsVirtualMachineUpdate(d *schema.ResourceData, meta interface{ log.Printf("[DEBUG] Resized OS Disk %q for Windows Virtual Machine %q (Resource Group %q) to %dGB.", diskName, id.Name, id.ResourceGroup, newSize) } + if d.HasChange("os_disk.0.disk_encryption_set_id") { + if diskEncryptionSetId := d.Get("os_disk.0.disk_encryption_set_id").(string); diskEncryptionSetId != "" { + diskName := d.Get("os_disk.0.name").(string) + log.Printf("[DEBUG] Updating encryption settings of OS Disk %q for Windows Virtual Machine %q (Resource Group %q) to %q..", diskName, id.Name, id.ResourceGroup, diskEncryptionSetId) + + disksClient := meta.(*clients.Client).Compute.DisksClient + + update := compute.DiskUpdate{ + DiskUpdateProperties: &compute.DiskUpdateProperties{ + Encryption: &compute.Encryption{ + Type: compute.EncryptionAtRestWithCustomerKey, + DiskEncryptionSetID: utils.String(diskEncryptionSetId), + }, + }, + } + + future, err := disksClient.Update(ctx, id.ResourceGroup, diskName, update) + if err != nil { + return fmt.Errorf("Error updating encryption settings of OS Disk %q for Windows Virtual Machine %q (Resource Group %q): %+v", diskName, id.Name, id.ResourceGroup, err) + } + + if err := future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting to update encryption settings of OS Disk %q for Windows Virtual Machine %q (Resource Group %q): %+v", diskName, id.Name, id.ResourceGroup, err) + } + + log.Printf("[DEBUG] Updating encryption settings of OS Disk %q for Windows Virtual Machine %q (Resource Group %q) to %q.", diskName, id.Name, id.ResourceGroup, diskEncryptionSetId) + } else { + return fmt.Errorf("Once a customer-managed key is used, you can’t change the selection back to a platform-managed key") + } + } + if shouldUpdate { log.Printf("[DEBUG] Updating Windows Virtual Machine %q (Resource Group %q)..", id.Name, id.ResourceGroup) future, err := client.Update(ctx, id.ResourceGroup, id.Name, update)