Module for cloudinit config in terraform


I am trying to create a module for the template_cloudinit_config data. The problem is that the config has become rather unwieldy and varied depending on the virtual machine I’m provisioning.

A big chunk of the cloud-init is the same for all virtual machines, but some parts vary.
For example I have something like this:

data "template_cloudinit_config" "prometheus" {
        # split in parts - 1st is cloud-init cfg as such; from 2nd onwards, shell scripts.
        # default gzip is true + base64 encoded (for proxmox and vsphere ova 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}/../shared/${var.hostname}/userdata.tpl", {
                        node_name = var.hostname
                        infra_ca = file("${path.module}/../certificate-transit/ca.crt")
                        consul_server_crt = tls_locally_signed_cert.prometheus.cert_pem
                        consul_server_key = tls_private_key.prometheus.private_key_pem
                        # we are using the same certificate for all consul instances at this point
                        consul_config = templatefile("${path.module}/../shared/consul/consul-config.tftpl", {
                                consul_datacenter = var.consul_datacenter
                                ui_config = var.ui_config
                                server_role = var.consul_server_role
                                bind_address = var.ip_address
                                bootstrap_expect = var.bootstrap_expect
                                retry_join = join(", ", [ for name in var.server_instance : format("%q", name["ip_address"]) ])
                                consul_domain = var.domain_suffix
                                consul_keygen = var.consul_keygen

which is mostly common for all virtual machines, but then for the kubernetes etcd nodes I have some certificates that end up in the cloud init config, such as:

                        etcd_ca_cert = vault_pki_secret_backend_intermediate_set_signed.kube1_etcd_ca.certificate
                        etcd_server_cert = vault_pki_secret_backend_cert.etcd_server[each.key].certificate

So my question is, would it be possible to conditionally add these directives depending on the virtual machine’s hostname? As far as I know, I could conditionally add/change the values of those variables, but I can’t add/remove the variables according to some external conditional, right?

I hope I was clearly enough, but let me know if I need to add more details/be more specific.

Maybe I should take a whole different approach here, but I’m not sure which.

I guess in this case I could get away with something to the effect of:

etcd_ca_cert = var.hostname == "etcd" ? vault_pki_secret_backend_intermediate_set_signed.kube1_etcd_ca.certificate : ""

And in the other template files (userdata.tpl) I wouldn’t have to define them at all, I guess.

I wonder if I can apply the same logic to the template files, such as:

kubeadm_config_file = templatefile("${path.module}/../shared/kubernetes/kubeadm-config.tpl", {
    node_name = each.key
    kube_join_token = var.kube_join_token
    kube_certificate_key = var.kube_certificate_key
    etcd_init_string = join(",", [ for name, v in var.kubernetes_servers : "${name}=https://${v["ip_address"]}:2380" if startswith(name, "omni-etcd-") ])

I’m sensing there are going to be some problems here, given that it’s multiline.

I’ll have to test it out.