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
Allow better lookup
default value for map of objects with optional attributes
#35027
Comments
Hi @bholzer, When I consider your whole writeup here, I understand the underlying need as something like: I'm trying to generate a value for a remote system that requires optional properties to be omitted when unset, rather than explicitly set to null, and it's hard to get from Terraform's idea of optional attributes to what the remote system expects. Do you think that's a valid interpretation of the problem you've encountered? I ask because when thinking about that topmost goal a more direct solution comes to my mind: a function that takes an arbitrary value of any type, visits all of the nested values if any, and for any object type or map type it removes any attribute/element whose value is null. Do you think that would be a viable replacement for the complicated expression you are trying to write in that local value? If we did want to offer such a function there are some tricky details to handle, but I think all solvable. Some initial thoughts:
This function therefore seems subtle enough that it deserves to be a built-in, and I've heard about this use-case of removing null values several times before so I think it's also common enough to justify being a built-in even if it were not so subtle. |
Thanks for taking the the time to take a look at this @apparentlymart. I realize this is somewhat unclear, sorry about that.
Not quite, although I think you've identified another thing that I encounter with some frequency: I find myself doing -- Trying to restate the problem that prompted this issue more concisely: There is no way to provide an empty object as a default when looking up objects that only have optional properties. A slimmed down example: variable "example" {
type = map(object({
prop = optional(string)
}))
default = {}
}
output "example" {
value = lookup(var.example, "missing", {})
} I recognize that the empty object is of a different type than the object specified in the variable and that's what causes the problem here, but it also seems reasonable to me that an object type with only optional properties can be thought of as "compactable" to an empty object. If I wanted to use output "example" {
value = {
for k, v in lookup(var.example, "missing", { prop = null }):
k => v if v != null
}
} |
Hi @bholzer, Thanks for the additional context! Unfortunately in your example the I think what this problem really seems to want is the general-purpose convert({}, object({
prop = optional(string)
})) This hypothetical function would allow performing the same type conversion behavior that is built into Unfortunately we've not been able to implement this function so far because it requires a breaking change to the language: it means that Terraform must treat identifiers like (This function broadly requires some kind of unification of the "value expression" and "type expression" concepts, so that type constraint expressions can be valid in locations where value expressions are expected. Today type constraint expressions are valid only in limited situations, such as in the In the meantime then I think I'm sorry I don't have a better answer. At least we can use this issue to represent the use-case. |
Note for future viewers: if you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions. Thanks! |
Terraform Version
Use Cases
I would like to provide a sane default lookup value for a map of objects with optional values.
My current specific use case:
I have a module that creates some AWS eventbridge schedules. I have a variable that I am using to allow consumers to override values of default schedules while at the same time providing custom schedules of their own.
Here's what it looks like right now:
I'm doing this to provide a flexible and easily configurable abstraction
Attempted Solutions
In my use case, note my usage of
try(local.default_schedules[name], {})
I'm doing this because
lookup(local.default_schedules, name, {})
does not work. I get an error:the default value must have the same type as the map elements
try
seems like a suboptimal solution here because I don't want to swallow other unspecified errors unexpectedly or anything like that.The solution suggested in the referenced issue also feels really unsatisfying. Fully specifying the entire object with null values is not something I'm going to do in this case.
Proposal
No response
References
This has been discussed a bit before, and it's said that this currently behaves as designed. That may be the case, but if so, I think the design should be changed to support a reasonable alternative.
#32417
The text was updated successfully, but these errors were encountered: