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.