Yamlencode and cloud-init configuration

Hello,

I would like to pass yaml to cloud-init through the openstack provider (resource openstack_compute_instance_v2 / field user_data.

Here is the code to generate the cloud-init config pass to the openstack_compute_instance_v2 resource.

data "template_cloudinit_config" "cloud_init_config" {
  count         = local.cloud_init_enable ? 1 : 0
  gzip          = true
  base64_encode = true

  part {
    filename     = "cloud-init-common.cfg"
    content_type = "text/cloud-config"
    content      = var.user_data_common
  }

Here is the code I would like to send:

user_data_common = yamlencode({
"bootcmd": [ "cloud-init-per", "always", "grow_VG", "pvresize", "/dev/vda2" ]

The result on the server is:

"bootcmd":
- "cloud-init-per"
- "always"
- "grow_VG"
- "pvresize"
- "/dev/vda2"

To work it should be:

bootcmd:
  - [ cloud-init-per, always, grow_VG, pvresize, /dev/vda2 ]

Any idea ?

Hi @smutel,

Both of the YAML examples you included at the end of your message seem equivalent to me. YAML is a flexible language that has many different ways to write the same data structure, but for a correct YAML parser there should be no difference in result between the style Terraform is generating (“block style”) and the style you suggested that you want it to generate (“flow style”).

There is no way to generate flow style with the yamlencode function. It always uses block style, unless generating empty collections.

I’ve seen cloud-init work with what yamlencode generates before, so I believe cloud-init correctly supports YAML and should be able to parse this. Are you sure that there isn’t some other problems occuring to make this fail? Do you see any specific errors in cloud-init’s logs?

According to your example, your bootcmd is supposed to be a list of lists of strings.

But you only have one set of [ ] so you just have a list of strings. Add another layer of [ ].

Ah yes, good catch @maxb. The flexibility of YAML got in the way of my understanding here, making me think these are equivalent when they aren’t. :confounded: