terraform

Heredoc vs indented heredoc


As per the documentation, I expected heredoc and indented heredoc to handle indentation differently. But they seem to be doing the same thing. What is surprising is that the indented heredoc doesn't trim the leading whitespaces based on the indentation level of the first line of text in the heredoc body.

Here is my code:

locals {
    here = <<EOF
One
    two
    three
    four
    EOF
}

locals {
    here_indented = <<-EOF
One
    two
    three
    four
    EOF
}

output "here" {
  value = local.here
}

output "here_indented" {
  value = local.here_indented
}

And here is the output:

  + here          = <<-EOT
        One
            two
            three
            four
    EOT
  + here_indented = <<-EOT
        One
            two
            three
            four
    EOT

What I expected:

  1. The normal heredoc should have thrown an error because the delimiter word "EOT" was indented
  2. The indented heredoc should have trimmed the leading spaces on lines 2 through 4 based on the fact that the first line was not indented

I tried printing the output as an interpolated string "${heredoc_indented}" but the result is the same.

What am I getting wrong here?


Solution

  • The special additional treatment for an "indented heredoc" is to count the number of space characters at the start of each line, find the line with the smallest number of spaces, and then remove that number of spaces from the prefix of all of the other lines.

    For example, with the following input:

      foo = <<-EOT
        hello
          world
      EOT
    

    The "hello" line starts with four spaces, and the "world" line starts with six spaces. Therefore the smallest number of spaces is four, and so Terraform removes four spaces from the start of each line.

    In the result then, the "hello" line starts with 4-4=0 spaces, while the "world" line starts with 6-4=2 spaces.

    Now let's consider the example from your question:

    locals {
        here_indented = <<-EOF
    One
        two
        three
        four
        EOF
    }
    

    In this case the "One" line starts with zero spaces, and so that's the smallest number of spaces. Therefore Terraform removes zero spaces from the start of each line, making this particular case behave essentially the same as the non-indented heredoc.