Closed bentterp closed 5 years ago
Hi @bentterp! Thanks for reporting this.
Are you using a build from latest master
here, or are you using one of the older alpha releases? I ask because I think you're seeing here the symptoms of hashicorp/hcl2#51, the fix for which should now be merged in to Terraform.
The alpha releases are several months old at this point, so they contain a number of bugs that have been fixed in the mean time. I'd recommend using a build from master
for this sort of testing now, until we get beta1 out, which we're expecting to release soon once we get provider releases in place that are compatible with it.
@apparentlymart Hi again :-) Sorry, I should have included that right away. I built against the master, and I've just verified again now after pulling so that I'm at this HEAD:
commit 1f4d2f4c5008cbf4e2da61b65f1cb98183bc4884
Merge: 3b18dd7 411df99
Author: James Bardin <j.bardin@gmail.com>
Date: Tue Feb 5 16:42:01 2019 -0500
Merge pull request #20235 from hashicorp/jbardin/id
(I can't use the alphas anyways, as they don't have the support for remote azurerm backend with CLI authenticatiion. So that's what got me into building on my own)
Thanks for confirming, @bentterp! We'll take a closer look at this after beta1, since our focus for beta1 is on testing the core<->provider interations, and we'll return to configuration language bugs for a subsequent beta.
In the mean time, if you happen to still have this error message handy, it'd be helpful to know if any specific part of the source code snippet you posted was underlined indicating a more precise position of the error. No worries if you don't still have it, or if nothing was underlined -- we can try to repro this ourselves to see -- but if you happen to have it handy already it may save some time in debugging this later on.
$ terraform plan
Error: Missing key/value separator
on locals.tf line 20, in locals:
19: mymap = {
20: for name,net in local.networks:
Expected an equals sign ("=") to mark the beginning of the attribute value. If
you intended to given an attribute name containing periods or spaces, write
the name in quotes to create a string literal.
"for name,net in local.networks:" - name is underscored (markdown won't let me underscore, though), ie the first word after "for" so "for" is interpreted as an attribute and not recognized as a reserved keyword.
Meanwhile, in case others run into this, I have worked around it by creating two lists and then zipping them:
mymap = zipmap(
[for name,net in local.networks: name],
[for name,net in local.networks: net.availability_zone],
)
When the bug is fixed, this config snippet can be changed to the more correct/efficient code without affecting input or output.
Thanks for that additional context and the workaround, @bentterp!
This still sounds suspiciously like the symptoms of hashicorp/hcl2#51, so I think we may need to revisit that change and see what it has missed for this problem to still be present.
If it is related to hashicorp/hcl2#51 then a different workaround may be to put the for
keyword on the same line as the brace:
mymap = { for name,net in local.networks: etc, etc }
(The issue with hashicorp/hcl2#51 was that it was sniffing ahead for the for
token after enabling newline-sensitive scanning, so the next token was the newline rather than the for
keyword and thus the parser thought it was parsing a normal { foo = bar, baz = beep }
sort of construct rather than the for
expression construct.)
That was spot on, @apparentlymart !! If I put the entire map declaration on one line, then it works. But it has to be everything on the same line, including the closing brace:
locals{
mymap = { for name,net in local.networks: name => net.availability_zone }
}
Any line breaks anywhere in that line causes the map generation to fail
Hi @bentterp! Sorry for the delay here.
It turns out that the previous fix here was insufficient.
The tricky thing with this construct is that {
can introduce either an object constructor or an object for
expression, and the former uses a newline-sensitive parsing mode (the object attributes are separated by newlines) while the for
expression is newline-agnnostic.
Our previous fixed handled the problem where the parser was switching to newline-sensitive mode too early, before even scanning for the for
token, and so it wouldn't match if it were on a newline. But that fix didn't handle the similar problem that the parser might already be in newline-sensitive mode due to parsing a block body (as in your case), and it wasn't forcing the mode off before peeking ahead for the for
token.
I've merged an upstream change to HCL that fixes the problem by managing the newline sensitivity mode more carefully, so this should now work in latest master, and the fix will be included in the forthcoming betas and final release.
Thanks again for reporting this!
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
Terraform Version
Terraform Configuration Files
Debug Output
Crash Output
Expected Behavior
I was hoping to get a map as output
Actual Behavior
No output, only errmsg
Steps to Reproduce
terraform apply
Additional Context
Obviously, this is not a configuration that I'm building but my attempt to understand the new for-loop syntax.... I just can't get it to work as in the documentation.
References