Contents

Managing Azure VM Disks and Extensions with Terraform: Handling Dependency and State Removal

When managing Azure Virtual Machines (VMs) with Terraform, especially Windows VMs with extensions and attached data disks, it’s common to encounter challenges around the order of resource destruction and avoiding unnecessary delays. This post summarizes practical solutions to these issues, with example commands and configuration snippets derived from a real-world scenario.

The Problem: Terraform Deletes Extensions and Disks Before the VM

By default, Terraform tracks each Azure VM extension (azurerm_virtual_machine_extension) and each data disk attachment (azurerm_virtual_machine_data_disk_attachment) as independent resources. When running terraform destroy, Terraform deletes these extensions and disk attachments one by one before deleting the VM.

This sequence can slow down the destroy process and sometimes cause failures if the VM or disks are not in the expected state. In Azure itself, deleting a VM automatically deletes extensions attached to it, making explicit extension destruction redundant.

Similarly, Terraform attempts to delete data disk attachments before the VM, which would cause the disk to be actually unattached from the running VM, with possible unexpected results.

Solution Overview: Managing Dependencies and Terraform State

1. Remove Extensions and Disk Attachments from Terraform State

To avoid Terraform explicitly deleting extensions and attachments, you can remove these resources from Terraform state, so Terraform forgets about them and lets Azure handle deletion cascades when the VM is deleted.

Use shell commands like these to bulk-remove all extensions or data disk attachments from your state:

# Remove all VM extensions from state
terraform state rm $(terraform state list | grep azurerm_virtual_machine_extension)

# Remove all data disk attachments from state
terraform state rm $(terraform state list | grep azurerm_virtual_machine_data_disk_attachment)

Note: Always back up your Terraform state file before performing bulk state removals.

Backup & restore the terraform state

Before performing any bulk state operations, it’s crucial to create a backup of your Terraform state file. Here is the recommended approach:

# Pull current state to a local backup file
terraform state pull > terraform.tfstate.backup.$(date +%Y%m%d_%H%M%S)

# Verify the backup contains your resources
terraform show terraform.tfstate.backup.$(date +%Y%m%d_%H%M%S)

To restore from backup if needed:

# For remote state, push the backup back
terraform state push terraform.tfstate.backup.20250105_143000

2. Enforce Disk-VM Destroy Ordering Using depends_on

Simply removing disk attachments from state can cause Terraform to try deleting disks before the VM, which fails if disks are still attached. The reliable fix is to add explicit dependencies so Terraform destroys resources in the correct order.

For example, in your VM resource definition, add a depends_on block referencing the disks, ensuring Terraform deletes disks after the VM:

resource "azurerm_windows_virtual_machine" "vm" {
  # VM configuration...

  depends_on = [
    azurerm_managed_disk.additionnal_disks,
    # add all relevant disk attachment resources here
  ]
}

This setup tells Terraform: wait until those disk attachments are destroyed before deleting the VM, avoiding the race condition that causes failure.

Why Explicit Dependencies?

Terraform often establishes implicit dependencies through references, but these sometimes represent only “resource existence,” not full “readiness.” Azure VM extensions and disk attachments require the VM to be fully provisioned (or deprovisioned) before related resources can be managed safely. The depends_on attribute forces Terraform to respect this ordering.

Summary Table: Terraform Destroy Behavior for Azure VM Components

Resource TypeDefault Terraform BehaviorRecommended Action
VM ExtensionsDestroyed first, then VMRemove from state before VM destroy, or leave as is if okay
Data Disk AttachmentsDestroyed before VMUse depends_on in VM to depend on disk attachments
Managed DisksDestroyed after attachmentsGenerally safe with proper dependencies
VMDestroy lastEnsure all dependencies cleared or ordered correctly

Final Recommendations

  • When destroying VMs with extensions, remove extensions from Terraform state to speed up destroy and rely on Azure’s automatic cleanup.
  • For disks, do not remove disk attachments or disks from state blindly. Instead, add explicit depends_on dependencies in the VM resource to ensure Terraform respects the correct destroy order.
  • Always backup your Terraform state before any bulk operations.
  • For quick environment cleanup, consider deleting the whole resource group which cascades deletes in Azure.

Terraform allows robust, repeatable management of complex Azure infrastructures, but some manual steps and explicit dependency handling are necessary to optimize operations involving VMs with extensions and attached data disks.

The approach described here — combining state resource removals and dependency declarations — has proven reliable in practice for ensuring clean, efficient VM destruction workflows.

Complete Example for Explicit Disk Dependency

resource "azurerm_virtual_machine_data_disk_attachment" "data_disk_1" {
  managed_disk_id    = azurerm_managed_disk.data_disk_1.id
  virtual_machine_id = azurerm_windows_virtual_machine.vm.id
  lun               = 0
  caching           = "ReadOnly"
}

resource "azurerm_windows_virtual_machine" "vm" {
  # VM configuration...

  depends_on = [
    azurerm_virtual_machine_data_disk_attachment.data_disk_1
  ]
}

Using these techniques will help you avoid errors during destruction and save time by preventing Terraform from destroying extensions and disk attachments needlessly.

If you have questions or want to share more tips on Terraform with Azure, feel free to comment below!


References and Further Reading

For additional information on the topics covered in this post, consider these resources:

Terraform Azure Provider Documentation

Dependency Management Best Practices

Community Solutions and Examples

Advanced Topics

Known Issues and Workarounds