New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defaults bug when nested type is map(string) #31177
Comments
Hi @theherk! Thanks for reporting this. It looks like you've encountered one of the common rough edges in the design of The
Since the element type of variable "storage" {
type = object({
name = string
enabled = optional(bool)
website = object({
index_document = optional(string)
error_document = optional(string)
})
documents = map(
object({
source_file = string
content_type = optional(string)
})
)
})
} In the subsequent call to storage = defaults(var.storage, {
# ...
# The "documents" attribute has a map type,
# so the default value represents defaults
# to be applied to all of the elements in
# the map, not for the map itself. Therefore
# it's a single object matching the map
# element type, not a map itself.
documents = {
# If _any_ of the map elements omit
# content_type then this default will be
# used instead.
content_type = "application/octet-stream"
}
}) Thankfully, this confusing situation will shortly become moot because we are intending to remove the Assuming we don't find an unexpected significant problem with that design in the meantime, it should hopefully be available for testing in an alpha release soon, in case you'd like to try it with your use-case. If we hear positive feedback about it during the alpha period then it will hopefully be stabilized in the next minor release, though it's too early to say for certain yet before there's been any external feedback at all. I think your example would look like this under the design implemented in that PR: variable "things" {
type = list(object({
inner = optional(object({
a = optional(string)
b = optional(map(string), {})
}))
}))
} Terraform will then handle the substitution of Including the default value as part of the I think given that the Thanks again! |
Okay. Thank you for the detailed explanation as always, @apparentlymart. The map handling is a bit counterintuitive for the reasons you specify, but the improvements proposed here and in the main thread really look good, and I'm excited to test it out. I'm still glad I went through this exercise because it was dizzying when trying to sort it out in a bigger implementation, so boiling it down helped to understand what was happening, even if not why. |
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. |
Terraform Version
Terraform Configuration Files
terraform.tfvars
Debug Output
Expected Behavior
Should have given:
Actual Behavior
Actually yields:
Steps to Reproduce
Additional Context
This example is contrived, and therefore may not seem practical, but the actual use case is more complex. This is just the minimum reproducible example.
I understand this is still being evaluated as noted recently in #19898, but I use it currently and this case I'm not sure the workaround.
You can see in the output
inners
thatb
is clearly{}
, so why can't we seem to match that?I even tried setting the
inner.b
default to{}
, but then I get the errorInvalid value for "defaults" parameter: .inner.b: invalid default value for string: string
. I find this even more baffling. This isn't a string. It ismap(string)
, so{}
should be a valid value, right?References
The text was updated successfully, but these errors were encountered: