How To Import An Azure Linux VM Without Recreating It

The public_ssh property can be a real PITA to validate, forcing you to recreate the VM if you try to import it.

Corey Regan's avatar

Published on September 20, 2024

2 min read


When you go to import an existing Azure Linux VM that was configured with an SSH key pair, Azure will give you a hint about the public key it expects, but it will fail when you copy/paste it.

Terraform will tell you what it expects to receive when setting admin_ssh_key:

bash:What Terraform expects for the admin_ssh_key block
$ terraform import azurerm_linux_virtual_machine.my_vm /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my_resource_group/providers/Microsoft.Compute/virtualMachines/my_vm
 
Terraform will perform the following actions:
 
  # azurerm_linux_virtual_machine.my_vm must be replaced
  # (imported from "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/my_resource_group/providers/Microsoft.Compute/virtualMachines/my_vm")
  # Warning: this will destroy the imported resource
-/+ resource "azurerm_linux_virtual_machine" "my_vm" {
      name = "my_vm"
 
      (redacted)
 
    - admin_ssh_key { # forces replacement
        - public_key = <<-EOT
              ---- BEGIN SSH2 PUBLIC KEY ----
              Comment: "description of ssh key here"
              (redacted)
              ---- END SSH2 PUBLIC KEY ----
          EOT -> null
      }
    }
 
Plan: 1 to import, 1 to add, 0 to change, 1 to destroy.

But if you configure the admin_ssh_key block to the suggestion, it'll fail:

terraform:Try the suggested admin_ssh_key block
resource "azurerm_linux_virtual_machine" "my_vm" {
  name = "my_vm"
 
  (redacted)
 
  admin_ssh_key {
    public_key = <<-EOT
                  ---- BEGIN SSH2 PUBLIC KEY ----
                  Comment: "description of ssh key here"
                  (redacted)
                  ---- END SSH2 PUBLIC KEY ----
                  EOT
    username   = "my_admin_username"
  }
}
shell:Error: decoding admin_ssh_key.0.public_key for public key data
 Error: decoding "admin_ssh_key.0.public_key" for public key data

   with azurerm_linux_virtual_machine.my_vm,
   on virtual_machines.tf line 39, in resource "azurerm_linux_virtual_machine" "my_vm":
   39: resource "azurerm_linux_virtual_machine" "my_vm" {

The Solution

The solution is rather simple: ignore the admin_ssh_key

terraform:Ignore the admin_ssh_key
resource "azurerm_linux_virtual_machine" "my_vm" {
  name = "my_vm"
 
  (redacted)
 
  lifecycle {
    ignore_changes = [
      admin_ssh_key, # Changing this forces VM replacement. Also needed to import the VM into Terraform
    ]
  }
}

Terraform is useful for initial setup, but past standing up the VM you should really use another tool like Ansible, Puppet, or Chef to manage your SSH keys on a machine.