-
Notifications
You must be signed in to change notification settings - Fork 9.6k
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() leaves child objects null #28344
Comments
Thanks for your feedback on this! I've relabelled this as an enhancement, as the I didn't contribute to the design of the
While it may not be aesthetically pleasing, I think this is the most viable workaround. Without more context of your use case, I can't be sure that this recommendation will work for you, but if there is one set of configuration options for zookeeper, flattening those out should hopefully work. |
For any future users that read this, you have two options:
|
So, option 2 above actually doesn't work if you provide a value; |
Thanks for sharing this feedback, @withernet! The main reason why this feature remains experimental is that there is still some unsettled debate about how to handle different kinds of omissions, so I appreciate you sharing your use-case here as a contribution to that discussion. The current design is aiming to allow modules to distinguish between an object being unset and an object being set with all of its attributes I understand is not a distinction that is relevant for your module and so you'd rather have the objects just always be set so you don't have to work around them sometimes being null. Unfortunately we've yet to establish a common base case that suits everyone's requirements, and so clearly some further design work is needed before we can finalize this feature. |
Why not add a parameter to |
Also want to confirm that even if you "flatten"; it's not usable at all. I just flattened our module and if you specify a single defined var, defaults just skips the rest of the object and leaves all the other variables |
Hi @withernet, Your feedback has been noted! This feature will remain experimental until we've found a suitable answer to all of the feedback, including this issue. Thanks! |
Just chiming in to say that I'm also experiencing this issue; currently I'm using option 2 (empty-declaring), but this isn't very sustainable, given how deeply-nested my config is, and flattening isn't an option. Unless the design of |
I disagree this issue should be viewed as an enhancement, and believe it should be marked as a bug. If the user is providing a default value using This appears to be a simple change in the Interim WorkaroundFor others looking for an interim solution, the nested object types can be provided as
(I had to mark the contents of As a handy helper for CLI runtime usage, the empty defaults template can be added to the description property of the variable for quick copy-and-pase:
This makes it much easier than remembering the structure required without opening the file again to inspect:
|
Thanks for pointing out this issue. We observe a similar behavior when a default value of an input variable is See this example. The default value for Terraform version
main.tf
terraform.tfvars
Expected output
Actual output
I would appreciate when this behavior could be well documented at least. A fix is welcomed. |
Using variable "conf" {
type = object({
description = string
name = string
namespace = string
params = list(object({
default = optional(string)
description = string
name = string
type = string
}))
resources = optional(object({
inputs = optional(list(object({
name = string
type = string
})))
outputs = optional(list(object({
name = string
type = string
})))
}))
results = optional(list(object({
name = string
description = string
})))
steps = list(object({
args = optional(list(string))
command = optional(list(string))
env = optional(list(object({
name = string
value = string
})))
image = string
name = string
resources = optional(object({
limits = optional(object({
cpu = string
memory = string
}))
requests = optional(object({
cpu = string
memory = string
}))
}))
script = optional(string)
workingDir = string
}))
})
}
locals {
conf = merge(
defaults(var.conf, {}),
{ for k, v in var.conf : k => v if v != null },
{ resources = { for k, v in var.conf.resources : k => v if v != null } },
{ steps = [for step in var.conf.steps : merge(
{ resources = {} },
{ for k, v in step : k => v if v != null },
)] },
)
} It would be convenient to have a function that would deeply remove keys with null values. |
Hi all, we recently released the Terraform v1.3 alpha, which includes the ability to mark object type attributes as optional and set default values. I'm following up with issues that have provided feedback on the previous experiment, and wanted to invite you all to try the alpha and provide any feedback on this updated design. You can learn more/add comments here. Thank you so much in advance, and hope you like the feature! |
Seeing the notification for this also made me realize we missed one when we were closing out some issues to represent that the For that reason I'm going to close this issue -- it's discussing a behavior of a feature that's no longer present in Terraform in the |
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
Debug Output
Not necessary
Crash Output
Not necessary
Expected Behavior
If I provide
var.my_var
with{}
and have defaults for all child objects, I expectdefaults()
to expand all child objects to include those defaults.Actual Behavior
Child objects remain
null
, see output:I understand this is by design: Terraform will recursively visit all of the attributes or elements of the nested value and repeat the same defaults-merging logic one level deeper.; this is a poor design. It means that no sub-objects can be optional at the root of the
type = object({})
; so therefore should change. It also leaves a bad impression when someone in the future Google's this only to learn that objects cannot be optional; which means the only way to fill in the defaults would be to removeoptional(object({}))
on the child objects, then requiring<object> = {}
just for terraform to expand the "default" value into the child object. This requirement kinda makes this functionality useless; I may as well just declare the whole value then instead of a whole bunch ofmy_obj = {}
, and so on.We have some config that goes pretty deep, for example:
The only way to make ☝️ work is to make only the primitive variables optional and then "empty" nest the object declarations. The other option would be to "flatten" the objects, but that doesnt look nearly as nice.
Steps to Reproduce
terraform plan
Additional Context
NA
References
module_variable_optional_attrs
causes panic #27385The text was updated successfully, but these errors were encountered: