dmacvicar / terraform-provider-libvirt

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

libvirt_domain disk: wwn constantly recalculated - constant changes #1033

Open alexs77 opened 9 months ago

alexs77 commented 9 months ago

System Information

Linux distribution

Red Hat Enterprise Linux release 8.8 (Ootpa)

Terraform version

Terraform v1.5.7
on linux_amd64
+ provider registry.terraform.io/dmacvicar/libvirt v0.7.1

Provider and libvirt versions

.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.1/linux_amd64/terraform-provider-libvirt_v0.7.1 0.7.1

Checklist

Description of Issue/Question

Setup

terraform {
  required_providers {
    libvirt = {
      source  = "dmacvicar/libvirt"
      version = "0.7.1"
    }
  }
}

provider "libvirt" {
  uri = "qemu:///system"
}

locals {
  default_volume_source_uri = "/data/templates/ubuntu.qcow2"
  images_directory = "/var/lib/libvirt/images"

  # From https://wiki.swisscom.com/x/ZkpsHw
  vm_name = "example-vm"
  vcpus   = "2"
  memory  = "4096"
}

resource "libvirt_domain" "default" {
  name        = local.vm_name
  vcpu        = local.vcpus
  memory      = local.memory

  disk {
    volume_id = libvirt_volume.os.id
    scsi      = true
  }
}

resource "libvirt_pool" "default" {
  name = local.vm_name
  path = join("/", [local.images_directory, local.vm_name])
  type = "dir"
}

resource "libvirt_volume" "default" {
  name   = basename(local.default_volume_source_uri)
  format = split(".", local.default_volume_source_uri)[length(split(".", local.default_volume_source_uri)) - 1]
  pool   = libvirt_pool.default.name
  source = local.default_volume_source_uri
}

# volume to attach to the "default" domain as OS disk
resource "libvirt_volume" "os" {
  # count=1

  name           = join("_", [local.vm_name, "os.qcow2"])
  base_volume_id = libvirt_volume.default.id
  format         = split(".", local.default_volume_source_uri)[length(split(".", local.default_volume_source_uri)) - 1]
  pool           = libvirt_pool.default.name
}

Steps to Reproduce Issue

terraform apply -auto-approve && terraform apply -auto-approve

[root@htcl-kvm-zbl-111 lv-bug] [DEV]# terraform apply -auto-approve && terraform apply -auto-approve
libvirt_pool.default: Refreshing state... [id=e34e17f7-ccdb-46a2-b2af-1b9eb19efd7a]
libvirt_volume.default: Refreshing state... [id=/var/lib/libvirt/images/example-vm/ubuntu.qcow2]
libvirt_volume.os: Refreshing state... [id=/var/lib/libvirt/images/example-vm/example-vm_os.qcow2]
libvirt_domain.default: Refreshing state... [id=69b89de7-c53f-435f-9e59-e389b2c923a8]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # libvirt_domain.default will be updated in-place
  ~ resource "libvirt_domain" "default" {
        id          = "69b89de7-c53f-435f-9e59-e389b2c923a8"
        name        = "example-vm"
        # (10 unchanged attributes hidden)

      ~ disk {
          - wwn       = "05abcd285c6230c9" -> null
            # (2 unchanged attributes hidden)
        }

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
libvirt_domain.default: Modifying... [id=69b89de7-c53f-435f-9e59-e389b2c923a8]
libvirt_domain.default: Modifications complete after 0s [id=69b89de7-c53f-435f-9e59-e389b2c923a8]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
libvirt_pool.default: Refreshing state... [id=e34e17f7-ccdb-46a2-b2af-1b9eb19efd7a]
libvirt_volume.default: Refreshing state... [id=/var/lib/libvirt/images/example-vm/ubuntu.qcow2]
libvirt_volume.os: Refreshing state... [id=/var/lib/libvirt/images/example-vm/example-vm_os.qcow2]
libvirt_domain.default: Refreshing state... [id=69b89de7-c53f-435f-9e59-e389b2c923a8]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # libvirt_domain.default will be updated in-place
  ~ resource "libvirt_domain" "default" {
        id          = "69b89de7-c53f-435f-9e59-e389b2c923a8"
        name        = "example-vm"
        # (10 unchanged attributes hidden)

      ~ disk {
          - wwn       = "05abcd285c6230c9" -> null
            # (2 unchanged attributes hidden)
        }

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
libvirt_domain.default: Modifying... [id=69b89de7-c53f-435f-9e59-e389b2c923a8]
libvirt_domain.default: Modifications complete after 0s [id=69b89de7-c53f-435f-9e59-e389b2c923a8]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

As can be seen there, the wwn attribute of the resource libvirt_domain.default => disk { … } would be reset for every run. This results in constant changes.

If libvirt_domain.default.disk.scsi is set to false, the issue does not surface.


Additional information:

Do you have SELinux or Apparmor/Firewall enabled? Some special configuration? Have you tried to reproduce the issue without them enabled?

n/a

alexs77 commented 9 months ago

It also seems to be impossible to override the wwn with a random string. In the source code, I'm now setting it to a fixed value:

resource "libvirt_domain" "default" {
  # …
  disk {
    volume_id = libvirt_volume.os.id
    scsi      = true
    wwn       = "2027eb2388d3f2e6"
  }
  # …
}

Runs of terraform apply -auto-approve && terraform apply -auto-approve show that the value is not stored.

libvirt_pool.default: Refreshing state... [id=e7d1e51b-87a0-4b9d-b580-2fafe7473cd5]
random_string.disk_os_wwn: Refreshing state... [id=2027eb2388d3f2e6]
libvirt_volume.default: Refreshing state... [id=/var/lib/libvirt/images/example/ubuntu.qcow2]
libvirt_volume.data[1]: Refreshing state... [id=/var/lib/libvirt/images/example/data_1.qcow2]
libvirt_volume.data[2]: Refreshing state... [id=/var/lib/libvirt/images/example/data_2.qcow2]
libvirt_volume.data[0]: Refreshing state... [id=/var/lib/libvirt/images/example/data_0.qcow2]
libvirt_volume.os: Refreshing state... [id=/var/lib/libvirt/images/example/example_os.qcow2]
random_string.disks_data_wwn[2]: Refreshing state... [id=0442395cc370fb38]
random_string.disks_data_wwn[1]: Refreshing state... [id=c44f1979e5109b54]
random_string.disks_data_wwn[0]: Refreshing state... [id=8e1b7db0d61e170c]
libvirt_domain.default: Refreshing state... [id=411e8833-9574-4c9e-94dd-c05371c9deb2]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # libvirt_domain.default will be updated in-place
  ~ resource "libvirt_domain" "default" {
        id          = "411e8833-9574-4c9e-94dd-c05371c9deb2"
        name        = "example"
        # (11 unchanged attributes hidden)

      ~ disk {
          ~ wwn       = "05abcdf8df2189e9" -> "2027eb2388d3f2e6"
            # (2 unchanged attributes hidden)
        }

        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
libvirt_domain.default: Modifying... [id=411e8833-9574-4c9e-94dd-c05371c9deb2]
libvirt_domain.default: Modifications complete after 0s [id=411e8833-9574-4c9e-94dd-c05371c9deb2]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
libvirt_pool.default: Refreshing state... [id=e7d1e51b-87a0-4b9d-b580-2fafe7473cd5]
random_string.disk_os_wwn: Refreshing state... [id=2027eb2388d3f2e6]
libvirt_volume.default: Refreshing state... [id=/var/lib/libvirt/images/example/ubuntu.qcow2]
libvirt_volume.data[2]: Refreshing state... [id=/var/lib/libvirt/images/example/data_2.qcow2]
libvirt_volume.data[1]: Refreshing state... [id=/var/lib/libvirt/images/example/data_1.qcow2]
libvirt_volume.data[0]: Refreshing state... [id=/var/lib/libvirt/images/example/data_0.qcow2]
libvirt_volume.os: Refreshing state... [id=/var/lib/libvirt/images/example/example_os.qcow2]
random_string.disks_data_wwn[0]: Refreshing state... [id=8e1b7db0d61e170c]
random_string.disks_data_wwn[1]: Refreshing state... [id=c44f1979e5109b54]
random_string.disks_data_wwn[2]: Refreshing state... [id=0442395cc370fb38]
libvirt_domain.default: Refreshing state... [id=411e8833-9574-4c9e-94dd-c05371c9deb2]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # libvirt_domain.default will be updated in-place
  ~ resource "libvirt_domain" "default" {
        id          = "411e8833-9574-4c9e-94dd-c05371c9deb2"
        name        = "example"
        # (11 unchanged attributes hidden)

      ~ disk {
          ~ wwn       = "05abcdf8df2189e9" -> "2027eb2388d3f2e6"
            # (2 unchanged attributes hidden)
        }

        # (2 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
libvirt_domain.default: Modifying... [id=411e8833-9574-4c9e-94dd-c05371c9deb2]
libvirt_domain.default: Modifications complete after 1s [id=411e8833-9574-4c9e-94dd-c05371c9deb2]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

As you can see, the wwn stays at 05abcdf8df2189e9.

otakup0pe commented 6 months ago

Confirming this seems to be happening to me as well. On Ubuntu 20.04.