Search code examples
terraformterraform-provider-azureterraform-template-file

How to pass multiple template files to user_Data variable in terraform


assign multiple templates files to user_Data variable. we dont want to merge this template in single file due to some architectural pattern .

I'm new to terraform so struggling on this.

data "template_file" "userdata_lin1" {
  template = <<EOF
#!/bin/bash
crontab cronjobfileremote
EOF
}

data "template_file" "userdata_lin2" {
  template = <<EOF
#!/bin/bash
echo "hello"
EOF
}

 user_data  = "${data.template_file.user_data1.rendered}"

Solution

  • It is a fundamental constraint of most cloud platforms that "user data" or "custom metadata" etc (terminology varies by vendor) is a single opaque string of bytes. The interpretation of those bytes depends on what software you have installed in your virtual machine image that makes use of it.

    A common choice of such software is cloud-init. If you are using cloud-init then the "user data" can be provided in a number of different formats.

    The main way to provide multiple distinct sections to cloud-init is via a MIME-Multipart archive, which is a concatenation of several values interspersed with headers to allow cloud-init to identify the boundaries and understand how you intend each part to be interpreted.

    Because cloud-init is a very common choice of software for interpreting "user data", Terraform has a cloudinit provider which includes a data source for constructing a MIME-Multipart archive.

    data "cloudinit_config" "example" {
      gzip          = false
      base64_encode = false
    
      part {
        content_type = "text/x-shellscript"
        filename = "userdata_lin1"
        content  = <<-EOF
          #!/bin/bash
          crontab cronjobfileremote
        EOT
      }
    
      part {
        content_type = "text/x-shellscript"
        filename = "userdata_lin2"
        content  = <<-EOF
          #!/bin/bash
          echo "hello"
        EOT
      }
    }
    

    You can then set your user_data argument to the output from this data source:

      user_data = data.cloudinit_config.example.rendered
    

    It's important to note that from the perspective of Terraform and from your cloud compute provider, the content of user_data is just an arbitrary string. Any issues in processing the string must be debugged within the target operating system itself, by reading the cloud-init logs to see how it interpreted the configuration and what happened when it tried to take those actions.