Terraform-provider-libvirt: Enhancement: Support for network storage volumes

Created on 10 Apr 2019  路  3Comments  路  Source: dmacvicar/terraform-provider-libvirt

One common use-case for libvirt_volumes would be using network devices. There is a whole list of different network storage options available in libvirt.
One example of network devices as backing store for the VM disks would be Ceph RBDs or iSCSI. Which is as far as I can see right now not currently not natively supported.

There currently is a way to do it with the included XSLT parameter for the volume which I assume was intended for this purpose but that is still a crude way to do it in the end. But I get it as due to the slew of different options available this is sadly not an easy one to implement.

RFC enhancement help wanted

Most helpful comment

Doing xslt again after so many years was entertaining. I'll probably make an update to the existing xslt example. But for now here is an example with rbd. I'll look into how this could be implemented in the future. Still have other things to work on currently.

data "template_file" "cephdisk" {
  template = "${file("${path.module}/templates/ceph_rbd.xml")}"
  vars {
    diskname = "${format(var.hostname_format, count.index)}.disk"
    ceph_user = "${var.libvirt_ceph_user}"
    ceph_uuid = "${var.libvirt_ceph_uuid}"
    ceph_pool = "${var.libvirt_ceph_pool}"
    ceph_mons = "${join("\n", formatlist("<host name='%s' port='6789' />", var.ceph_mons))}"
  }

  count = "${var.hosts}"
}

resource "libvirt_volume" "coreos-disk" {
  name   = "${format(var.hostname_format, count.index)}.disk"
  pool     = "${var.libvirt_ceph_pool}"
  format  = "raw"
}

resource "libvirt_domain" "coreos-machine" {
  [...]
  xml {
    xslt = "${data.template_file.cephdisk.rendered}"
  }
}
<?xml version="1.0" ?>
<!-- templates/ceph_rbd.xml -->
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/domain/devices/disk[source/@volume='${diskname}']">
    <disk type='network' device='disk'>
      <xsl:copy-of select="driver" />
      <auth username='${ceph_user}'>
        <secret type='ceph' uuid='${ceph_uuid}' />
      </auth>
      <source protocol='rbd' name="{concat('${ceph_pool}/', source/@volume)}">
        ${ceph_mons}
      </source>
      <xsl:copy-of select="target" />
      <xsl:copy-of select="address" />
    </disk>
  </xsl:template>
</xsl:stylesheet>

All 3 comments

thx . yes as you stated the xslt feature should cover the missing GAP between this provider and the libvirt API. ( https://github.com/dmacvicar/terraform-provider-libvirt#introduction--goals)

Doing xslt again after so many years was entertaining. I'll probably make an update to the existing xslt example. But for now here is an example with rbd. I'll look into how this could be implemented in the future. Still have other things to work on currently.

data "template_file" "cephdisk" {
  template = "${file("${path.module}/templates/ceph_rbd.xml")}"
  vars {
    diskname = "${format(var.hostname_format, count.index)}.disk"
    ceph_user = "${var.libvirt_ceph_user}"
    ceph_uuid = "${var.libvirt_ceph_uuid}"
    ceph_pool = "${var.libvirt_ceph_pool}"
    ceph_mons = "${join("\n", formatlist("<host name='%s' port='6789' />", var.ceph_mons))}"
  }

  count = "${var.hosts}"
}

resource "libvirt_volume" "coreos-disk" {
  name   = "${format(var.hostname_format, count.index)}.disk"
  pool     = "${var.libvirt_ceph_pool}"
  format  = "raw"
}

resource "libvirt_domain" "coreos-machine" {
  [...]
  xml {
    xslt = "${data.template_file.cephdisk.rendered}"
  }
}
<?xml version="1.0" ?>
<!-- templates/ceph_rbd.xml -->
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/domain/devices/disk[source/@volume='${diskname}']">
    <disk type='network' device='disk'>
      <xsl:copy-of select="driver" />
      <auth username='${ceph_user}'>
        <secret type='ceph' uuid='${ceph_uuid}' />
      </auth>
      <source protocol='rbd' name="{concat('${ceph_pool}/', source/@volume)}">
        ${ceph_mons}
      </source>
      <xsl:copy-of select="target" />
      <xsl:copy-of select="address" />
    </disk>
  </xsl:template>
</xsl:stylesheet>

I would like to implement at least the libvirt_domain.disk.rbd in the near future to alleviate the requirement for XSLT in our use-case.

resource "libvirt_domain" "test" {
  disk {
    volume_id = "${libvirt_volume.test.id}"
    rbd = {
      user = ""
      uuid = ""
      pool = ""
      mons = [
        ...
      ]
    }
  }
}

This should be fairly easy to implement but would still require the clone option for the libvirt_volume

Was this page helpful?
0 / 5 - 0 ratings

Related issues

arunnalpet picture arunnalpet  路  3Comments

muroj picture muroj  路  3Comments

alkersan picture alkersan  路  5Comments

oswee picture oswee  路  4Comments

lifeofguenter picture lifeofguenter  路  5Comments