How to identify libvirt_volume id in terraform for reuse in split configuration files

kvm-virtualizationterraform

Setup

I am using a remote state files that are stored on external cloud storage and my terraform resources are split in different modules. I want to download the base images only once in an images module and would like to reference them in the definitions of each domain I want to create.
Both the domain as well as the image file are defined by a 3rd party terraform provider for libvirt. The state files are separated by component as terraform would like to destroy resources when terraform apply-ing the desired state for individual components one at a time.

https://github.com/dmacvicar/terraform-provider-libvirt

Terraform Code

images/main.tf

resource "libvirt_volume" "centos-7" {
   name = "centos-7.qcow2"
   pool = "default"
   source = "http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2"
   format = "qcow2"
}

bastion-host/main.tf

# Create a volume to attach to the "mgmt_bastion" domain as main disk
resource "libvirt_volume" "mgmt_bastion_volume" {
   name = "mgmt_bastion.qcow2"
   base_volume_id = "${libvirt_volume.centos-7.id}"
}

terraform.state

libvirt_volume.centos-7:
  id = /var/lib/libvirt/images/centos-7.qcow2
  format = qcow2
  name = centos-7.qcow2
  pool = default
  size = 8589934592
  source = http://cloud.centos.org/centos/7/images/CentOS-7-x86_64-GenericCloud.qcow2

Issue

The resources work fine when I define them in the same terraform configurations. However each domain then would like to download the same base image. The state files are separated so that building one domain would not delete other domains/resources that are not defined in a particular main.tf file. When I define the image outside in a different module, of course I cannot reference it:

Error: resource 'libvirt_volume.mgmt_bastion_volume' config: unknown resource 'libvirt_volume.centos-7' referenced in variable libvirt_volume.centos-7.id

Possible solutions / What I've tried

When using cloud providers like AWS, usually this is not an issue and may be solved by configuring data sources and filtering.
https://www.terraform.io/docs/configuration/data-sources.html

However using the libvirt provider requires some extra thoughts.

I know how to terraform show in order to inspect the current terraform state files of another component. There I can read the ids from tbe shell.

Maybe I just have to run an external script in order to fill a variable with the id that I can then repeatedly use in terraform dsl.

Maybe I have to hardcode the id. Seems like it I can use the path for that: /var/lib/libvirt/images/centos-7.qcow2
However I am no friend of hardcoding and I my tests showed, that some images additionally contain uuids to reference them:
/var/lib/libvirt/images/commoninit.iso;5a79dcf5-4420-5169-b9f4-5340e9904944

Therefore I would like to learn a better way to solve this generically when next time the resource is not so easily identifyable.

Edit:

Hardcoding the path did not work:

libvirt_volume.mgmt_bastion_volume: Creating...
  base_volume_id: "" => "centos-7.qcow2"
  name:           "" => "mgmt_bastion.qcow2"
  pool:           "" => "default"
  size:           "" => "<computed>"
Failed to save state: Resource not found

True for full and partial path to the image file.

Questions

  • How do I get the id of the already downloaded file in order to specify it as CoW backing volume? (without manually looking into the state files and hardcoding the id)
  • Is there a better way to reference the same cloud image in different terraform definitions without downloading it again? After all, I want to reference the same base image to generate lots of libvirt domains in a space efficient manner.

Best Answer

After further investigation I found the answer to my own question:

The base_volume_id has to be used with the full path to the target volume (default pool has the path: /var/lib/libvirt/images).

The state file contained the component name separated with '/'. This caused an issue to write the state file on the cloud storage. I fi

Related Topic