Search code examples
terraformcoreos-ignition

Terraform: YAML file rendering issue in storage section of container linux config of flatcar OS


I am trying to generate a file by template rendering to pass to the user data of the ec2 instance. I am using the third party terraform provider to generate an ignition file from the YAML.

data "ct_config" "worker" {
  content      = data.template_file.file.rendered
  strict       = true
  pretty_print = true
}
data "template_file" "file" {
  ...
  ...
  template = file("${path.module}/example.yml")
  vars = {
    script = file("${path.module}/script.sh")
  }
}

example.yml

storage:
  files:
    - path: "/opt/bin/script"
      mode: 0755
      contents: 
        inline: |
          ${script}

Error:

Error: Error unmarshaling yaml: yaml: line 187: could not find expected ':'

  on ../../modules/launch_template/launch_template.tf line 22, in data "ct_config" "worker":
  22: data "ct_config" "worker" {

If I change ${script} to sample data then it works. Also, No matter what I put in the script.sh I am getting the same error.


Solution

  • You want this outcome (pseudocode):

    storage:
      files:
        - path: "/opt/bin/script"
          mode: 0755
          contents: 
            inline: |
              {{content of script file}}
    

    In your current implementation, all lines after the first loaded from script.sh will not be indented and will not be interpreted as desired (the entire script.sh content) by a YAML decoder.

    Using indent you can correct the indentation and using the newer templatefile functuin you can use a slightly cleaner setup for the template:

    data "ct_config" "worker" {
      content      = local.ct_config_content
      strict       = true
      pretty_print = true
    }
    
    locals {
      ct_config_content = templatefile("${path.module}/example.yml", {
        script = indent(10, file("${path.module}/script.sh"))
      })
    }
    

    For clarity, here is the example.yml template file (from the original question) to use with the code above:

    storage:
      files:
        - path: "/opt/bin/script"
          mode: 0755
          contents: 
            inline: |
              ${script}