Files
coder/examples/templates/azure-linux
blinkagent[bot] 0f6fbe7736 chore(examples): clarify azure-linux resource lifecycle on stop vs delete (#22150)
The existing README for the Azure Linux starter template only mentioned
that the VM is ephemeral and the managed disk is persistent, but did not
explain that the resource group, virtual network, subnet, and network
interface also persist when a workspace is stopped.

This led to confusion where users expected all Azure resources to be
cleaned up on stop, when in reality only the VM is destroyed.

## Changes

- Added the persistent networking/infrastructure resources to the
resource list
- Added "What happens on stop" section explaining which resources
persist and why
- Added "What happens on delete" section confirming all resources are
cleaned up
- Moved the existing note about ephemeral tools/files into a "Workspace
restarts" subsection for clarity

These changes exactly mirror https://github.com/coder/registry/pull/713
since the registry is not yet linked to the starter templates in
`coder/coder`. Once the registry is linked, the starter templates will
pull from the registry and this duplication will no longer be necessary.

---------

Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
2026-02-19 10:53:05 -06:00
..

display_name, description, icon, maintainer_github, verified, tags
display_name description icon maintainer_github verified tags
Azure VM (Linux) Provision Azure VMs as Coder workspaces ../../../site/static/icon/azure.png coder true
vm
linux
azure

Remote Development on Azure VMs (Linux)

Provision Azure Linux VMs as Coder workspaces with this example template.

Prerequisites

Authentication

This template assumes that coderd is run in an environment that is authenticated with Azure. For example, run az login then az account set --subscription=<id> to import credentials on the system and user running coderd. For other ways to authenticate, consult the Terraform docs.

Architecture

This template provisions the following resources:

  • Azure VM (ephemeral, deleted on stop)
  • Managed disk (persistent, mounted to /home/coder)
  • Resource group, virtual network, subnet, and network interface (persistent, required by the managed disk and VM)

What happens on stop

When a workspace is stopped, only the VM is destroyed. The managed disk, resource group, virtual network, subnet, and network interface all persist. This is by design — the managed disk retains your /home/coder data across workspace restarts, and the other resources remain because the disk depends on them.

This means you will see these Azure resources in your subscription even when a workspace is stopped. This is expected behavior.

What happens on delete

When a workspace is deleted, all resources are destroyed, including the resource group, networking resources, and managed disk.

Workspace restarts

Since the VM is ephemeral, any tools or files outside of the home directory are not persisted across restarts. To pre-bake tools into the workspace (e.g. python3), modify the VM image, or use a startup script. Alternatively, individual developers can personalize their workspaces with dotfiles.

Note

This template is designed to be a starting point! Edit the Terraform to extend the template to support your use case.

Persistent VM

Important

This approach requires the az CLI to be present in the PATH of your Coder Provisioner. You will have to do this installation manually as it is not included in our official images.

It is possible to make the VM persistent (instead of ephemeral) by removing the count attribute in the azurerm_linux_virtual_machine resource block as well as adding the following snippet:

# Stop the VM
resource "null_resource" "stop_vm" {
  count      = data.coder_workspace.me.transition == "stop" ? 1 : 0
  depends_on = [azurerm_linux_virtual_machine.main]
  provisioner "local-exec" {
    # Use deallocate so the VM is not charged
    command = "az vm deallocate --ids ${azurerm_linux_virtual_machine.main.id}"
  }
}

# Start the VM
resource "null_resource" "start" {
  count      = data.coder_workspace.me.transition == "start" ? 1 : 0
  depends_on = [azurerm_linux_virtual_machine.main]
  provisioner "local-exec" {
    command = "az vm start --ids ${azurerm_linux_virtual_machine.main.id}"
  }
}