dmacvicar / terraform-provider-libvirt

Terraform provider to provision infrastructure with Linux's KVM using libvirt
Apache License 2.0
1.58k stars 457 forks source link

Adding a new disk forces recreation and changes domain id and mac address(es) #751

Open gthieleb opened 4 years ago

gthieleb commented 4 years ago

System Information

Linux distribution

Fedora 31

Terraform version

 terraform --version
Terraform v0.12.26
+ provider.libvirt (unversioned)

Provider and libvirt versions

$ ~/.terraform.d/plugins/linux_amd64/terraform-provider-libvirt  --version
/home/gthieleb/.terraform.d/plugins/linux_amd64/terraform-provider-libvirt d1cf93cdb066b2d3d2c2c046d2fb986808d9a424
Compiled against library: libvirt 5.6.0
Using library: libvirt 5.6.0
Running hypervisor: QEMU 4.1.1
Running against daemon: 5.6.0

Checklist

Description of Issue/Question

Update an existing template by adding a new disk forces recreation of the domain. This leads to generation of a new mac address and new device ids.

I make use of the mac_address for a custom cloud-init iso (The usage scenario is multi nic VM setups). It is created after creation of the libvirt_domain based on the output of a previous terraform apply command.

Setup

# we need to use the local qemu connection string here
provider "libvirt" {
  uri = "qemu:///system"
}

resource "libvirt_volume" "vol" {
  name = "centos-test.qcow2"
  pool = "vm-pool"
  source = "/data/vms/templates/centos-packer.qcow2"
  format = "qcow2"
}

# Create the machine
resource "libvirt_domain" "vm" {
  # run state is controlled by ansible
  running = "false"
  name = "centos-test"
  memory = "2048"
  vcpu = 2
  network_interface {
    # we only provide the name of the existing
    network_name = "default"
  }
  disk {
       volume_id = libvirt_volume.vol.id
  }
  graphics {
    type = "spice"
    listen_type = "address"
    autoport = "true"
  }
}
output "libvirt_domain" {
  value = libvirt_domain.vm
}

Steps to Reproduce Issue

  1. Perform terraform apply using the template above
  2. Add an additional device entry to the terraform template (Its an ISO that points to the custom cloudinit iso).
    disk {
       file = "/data/isos/centos-test_cloudinit.iso"
    }
  3. Perform terraform apply again.

Current Behavior

terraform plan

Terraform will perform the following actions:

  # libvirt_domain.vm must be replaced
-/+ resource "libvirt_domain" "vm" {
      ~ arch        = "x86_64" -> (known after apply)
      - autostart   = false -> null
      - cmdline     = [] -> null
      ~ disk        = [ # forces replacement
          ~ {
              ~ block_device = "" -> null
              ~ file         = "" -> null
              ~ scsi         = false -> null
              ~ url          = "" -> null
                volume_id    = "/data/vms/centos-test.qcow2"
              ~ wwn          = "" -> null
            } # forces replacement,
          - {
              - block_device = ""
              - file         = "/data/isos/centos-test_cloudinit.iso"
              - scsi         = false
              - url          = ""
              - volume_id    = ""
              - wwn          = ""
            },
        ]
      ~ emulator    = "/usr/bin/qemu-system-x86_64" -> (known after apply)
        fw_cfg_name = "opt/com.coreos/config"
 =>     ~ id          = "3a13b2ec-675e-468f-9604-1d5cc648d204" -> (known after apply)
      ~ machine     = "pc" -> (known after apply)
        memory      = 2048
        name        = "centos-test"
        qemu_agent  = false
        running     = false
        vcpu        = 2

        graphics {
            autoport       = true
            listen_address = "127.0.0.1"
            listen_type    = "address"
            type           = "spice"
        }

      ~ network_interface {
          ~ addresses      = [] -> (known after apply)
          + hostname       = (known after apply)
=>          ~ mac            = "52:54:00:E6:8C:D0" -> (known after apply)
          ~ network_id     = "e5aa58e6-5bd6-4adb-98b2-5a85c358003b" -> (known after apply)
            network_name   = "default"
          - wait_for_lease = false -> null
        }
    }

terraform apply

=>   "id" = "cb2c39aa-e4cc-45be-9f4e-3b5a73c44110"
  "initrd" = ""
  "kernel" = ""
  "machine" = "pc"
  "memory" = 2048
  "name" = "centos-test"
  "network_interface" = [
    {
      "addresses" = []
      "bridge" = ""
      "hostname" = ""
 =>     "mac" = "52:54:00:EA:2D:EA"
      "macvtap" = ""
      "network_id" = "e5aa58e6-5bd6-4adb-98b2-5a85c358003b"
      "network_name" = "default"
      "passthrough" = ""
      "vepa" = ""
      "wait_for_lease" = false
    },
  ]

Desired behavior

Terraform apply should not recreate the domain. Alternativel it should set mac and domain id to its former values.

sspreitzer commented 3 years ago

Is there any progress on this one? Would love to be able to attach disks on the fly.

scabala commented 1 week ago

Related to #1069