Ask questionsDetect incorrect directive syntax {% and provide appropriate error message

I followed and came to a conclusion that iterating over maps in templates doesn't seem to be working.

I don't know if it's supposed to be working, but if not then the error message doesn't make it obvious.

Terraform Version

0.12 master (f199030739856971c1de542cd35aa52db9a08399)

Terraform Configuration Files

locals {
  list_var = ["one", "two", "three"]
  map_var = {
    first  = "hello world"
    second = "hi there"
    third  = "woof!"

resource "local_file" "vcsa" {
  content = templatefile("${path.module}/example.tpl.txt", {
    list_var = local.list_var
    map_var  = local.map_var
  filename = "${path.module}/example.txt"


{% for key, value in map_var }
key = ${key}
value = ${value}
{% endfor ~}

{% for element in list_var }
{% endfor ~}

Expected Behavior

Created a new file example.txt with the following content:

key = first
value = hello world
key = second
value = hi there
key = third
value = woof!


Actual Behavior

Error: Invalid function argument

  on line 11, in resource "local_file" "vcsa":
  11:   content = templatefile("${path.module}/example.tpl.txt", {
    | local.list_var is tuple with 3 elements
    | local.map_var is object with 3 attributes

Invalid value for "vars" parameter: vars map does not contain key "key",
referenced at ./example.tpl.txt:3,9-12.

The snippet in the diagnostic could be improved also (and display code for arguments on lines 12+), but that's unrelated to this issue, I think.

Steps to Reproduce

terraform apply


Answer questions apparentlymart

I'm not sure what's going on here yet, but this error comes from the reference pre-check, which suggests that expr.Variables is not behaving correctly in this situation.

The expected behavior for Variables is to return only traversals that access the root scope. Any references to temporary local names created in for expressions and for template sequences should be excluded.

When participating in a tree walk, ForExpr (which is the AST node for both for expressions and template for sequences) introduces a ChildScope node to signal that some names are hidden by a nested scope. It seems like for some reason the reference to key inside the block is not being detected as being hidden by the child scope, which suggests perhaps a tree walk bug.

It'd be interesting to see if this affects for expressions in the main language too, since most of the implementation is shared. Terraform itself does a similar pre-check of references before evaluation in order to know what it needs to load from the state, so if this bug were present in for expressions I'd expect to see a failure that suggests that the name key is being understood as a resource type.

Github User Rank List