Templating in deployment of virtual machines in terraform


If I wanted to deploy several virtual machines (let’s say on proxmox, but this applies to vmware too in my case), is there a way to use templates so that I don’t have to recopy the whole code for each resource "proxmox_vm_qemu" "proxmox_vm" stanza?
So I’m referring to this:

resource "proxmox_vm_qemu" "proxmox_vm" {
        for_each = var.consul_servers

        # cloud-init config needs to exist before continuing
        depends_on = [
        name = "${each.key}"
        target_node = var.targetnode

        # provision from clone:
        clone = "consul-20.04"
        os_type = "cloud-init"

        # cloud-init options:
        cicustom = 'user=cloudinit:snippets/userdata-${each.key}.yaml,meta="local-hostname: ${each.key}"'
        ipconfig0 = "ip=${each.value["ip_address"]}/24,gw=${var.gw}"
        nameserver = ""
        searchdomain = "company.internal"

        # assign resources and set general options:
        cores = "2"
        sockets = "1"
        cpu = "kvm64"
        memory = "2048"
        # minimum amount of memory:
        balloon = "0"
        scsihw = "virtio-scsi-pci"
        bootdisk = "scsi0"
        boot = "c"
        force_create = "false"
        bios = "seabios"
        agent = 1
        numa = true
        hotplug = "network,disk,memory,cpu"
        disk {
          size = "30G"
          type = "scsi"
          storage = "local-lvm"
          ssd = "0"
        network {
          model = "virtio"
          bridge = "vmbr1"
        serial {
          id = "0"
          type = "socket"

So I’d like to have another deployment, but with a different name and, let’s say, a different cloud-init configuration. Would it be possible to use some defaults so that I don’t have to repeat the whole stanza?


Terraform does have modules: Modules Overview - Configuration Language | Terraform by HashiCorp

These are an effective way to wrap up a collection of resources that need to be re-used, with some values parameterised.

However, they do come with some inflexible downsides:

  • Every value you need to be able to parameterise from outside the module needs to be explicitly redeclared as an input variable to the module.
  • Migrating existing infrastructure that has already been provisioned using an ordinary resource block, into a module, requires sometimes-complex editing of the Terraform state.

So, if you’re still at an experimental phase, just copy/pasting the existing block, may, sadly, turn out to be easier.

1 Like