Render a template inside a cloud-init config file

Hello,

I’m trying to use a template inside the cloud-init config file and the only thing I’ve come up with is the following:

data "template_file" "consul_config" {
        template = file("${path.module}/files/consul-config.tftpl")
        vars = {
                consul_datacenter = var.consul_datacenter
                ui_config = var.ui_config
                server_role = var.server_role
                retry_join = var.retry_join
                consul_domain = var.consul_domain
        }
}
# In Terraform 0.12 and later, the templatefile function offers a built-in mechanism for rendering a template from a file. Use that instead of `template_file` data source.

# Source the cloud-init config file
data "template_cloudinit_config" "consul" {
        for_each = var.consul_servers

        # split in parts - 1st is cloud-init cfg as such; from 2nd onwards, shell scripts.
        # default gzip is true + base64 encoded (for proxmox don't encode or zip the cloud-init)
        gzip = false
        base64_encode = false
        part {
                filename = "cloud-init.cfg"
                content_type = "text/cloud-config"
                content = templatefile("${path.module}/files/userdata.tpl", {
                        root_ssh_key = file("${path.module}/files/id_ed25519.pub")
                        consul_config = data.template_file.consul_config.rendered
                })
        }
}

The issue I have with this is that the terraform documentation clearly states that you should switch to templatefile function instead of using the template_file data. In this case I used the latter simply because I don’t know how I would be able to integrate it in the template_cloudinit_config stanza.

Is there any way I can write this better? Any help is much appreciated!

Hi @lethargosapatheia!

The result of templatefile is just another string, so there’s no reason why you can’t use another call to templatefile with a different template as the definition of one of your variables passed to the outer template.

For example:

content = templatefile("${path.module}/files/userdata.tpl", {
  root_ssh_key = file("${path.module}/files/id_ed25519.pub")
  consul_config = templatefile("${path.module}/files/consul-config.tftpl", {
    consul_datacenter = var.consul_datacenter
    ui_config         = var.ui_config
    # (etc...)
  })
})
1 Like

Thank you, I appreciate it. I tried it initially, but I had made a mistake and I thought that it wouldn’t work :slight_smile: