0.9.2
Please list the resources as a list, for example:
variable "map" {
type = "map"
default = {
map = { thing = "stuff" }
}
}
data "null_data_source" "nds" {
inputs = {
d = "${1 > 0 ? var.map["map"] : map() }"
}
}
output "map map" {
value = "${var.map["map"]}"
}
output "map map ternary" {
value = "${1 > 0 ? var.map["map"] : map() }"
}
output "map map ternary from nds" {
value = "${data.null_data_source.nds.inputs.d}"
}
I'm not including debug output, it's easier to do on your own than download a gist
There's no panic
I should have gotten the map value for var.map["map"] in all cases
When the null_data_source is commented out, the "map map ternary" output simply fails to output anything. terraform exits normally, and only produces output for "map map"
When the NDS was added, here is the error:
1 error(s) occurred:
* data.null_data_source.nds: 1 error(s) occurred:
* data.null_data_source.nds: At column 3, line 1: true and false expression types must match; have type list and type map in:
${1 > 0 ? var.map["map"] : map() }
So the ternary type detection is broken, which is causing spurious errors. Furthermore, when you attempt a ternary in an output variable and the type detection brokenness is triggered, the error is simply swallowed, and the output never appears, as terraform claims a normal exit status.
Please list the steps required to reproduce the issue, for example:
terraform applyWhy do I keep finding these core bugs?
Couldn't find a thing
If someone would be kind enough to propose a workaround for this one, I'd be very glad.
Hi @in4mer! Sorry for all the confusing interactions here.
The fact that the error isn't returned when this expression appears in an output is the same root cause as #9080.
Unfortunately I think this other problem here, with your map being detected as a list, is a gross problem with the HCL parser. HCL has various "sloppy" interpretations of certain constructs to allow for different forms of configuration block, and in particular it often likes to turn single maps into slices of maps, as a side-effect of the fact that you can potentially repeat blocks:
foo {}
foo {}
I _think_ what's going on here is that HCL is interpreting what you intended to be a map of maps as a map of lists of maps, which the type checker in the interpolation language is then (correctly) rejecting.
In general deeply-nested structures like this don't work very well in Terraform right now. We have some plans to improve how types are represented internally, since today things are built on rather shaky foundations that date back to when Terraform only supported strings.
For now a workaround here is a bit tricky. Normally in this sort of situation we suggest using the map() interpolation function to bypass HCL's weird parsing rules, but interpolations are not allowed in variable defaults and so this solution won't work here.
So unfortunately I think for now my only suggestion is to avoid using multi-level nested data structures like this, and instead flatten the parameters to be lists of strings or maps of strings. I understand that this is an annoying restriction, and we are already discussing internally the solution to this class of problem to give Terraform a better handle on collection types.
errors are eaten

Thank you very much for sending this bug report.
Issue is broader than nested maps. If it's not clear in the above discussion:
main.tf
terraform {
required_version = ">= 0.10.7"
}
variable "config" {
type = "map"
default {
Foo = "hello"
Bar = "world"
}
}
variable "config2" {
type = "map"
default {}
}
output "test_output" {
value = "out"
}
output "test" {
value = "${("true" ? var.config : var.config2 )}"
}
Terminal:
terraform apply
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
test_output = out
Semi-related note:
I was trying to get interpolation in default values by using a map in the locals feature and faced similar issues with the ternary operator... but this case may be more similar to the nesting of maps, I haven't looked at the internals.
Any update on this issue? We have the same issue on version 0.10.7
Hi all!
The core issue regarding conditional statements has been fixed.
The example in the original comment will not work, but now terraform gives a clear error message explaining that inputs must be strings:
Error: Incorrect attribute value type
on main.tf line 9, in data "null_data_source" "nds":
9: inputs = {
Inappropriate value for attribute "inputs": element "d": string required.
The latter example works as expected:
variable "config" {
type = "map"
default = {
Foo = "hello"
Bar = "world"
}
}
variable "config2" {
type = "map"
default = {}
}
output "test_output" {
value = "out"
}
output "test" {
value = "${("true" ? var.config : var.config2 )}"
}
$ terraform output
test = {
"Bar" = "world"
"Foo" = "hello"
}
test_output = out
Based on that, I am going to close this issue. Please don't hesitate to open a new issue if you see any odd behaviors in terraform 0.12. Thanks!
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.
Most helpful comment
Issue is broader than nested maps. If it's not clear in the above discussion:
main.tf
Terminal:
Semi-related note:
I was trying to get interpolation in default values by using a map in the locals feature and faced similar issues with the ternary operator... but this case may be more similar to the nesting of maps, I haven't looked at the internals.