-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
Optional arguments in object variable type definition #19898
Comments
I'd really like to have this option too. Any plans of prioritizing this enahancement ? |
is there a workaround for this? I found myself using type=any |
@rverma-nikiai No, there is not currently a workaround for this. The best thing we can do is define the optional argument as such (where
variable "foo" {
type = object({
name = string
id = number
foobar = string # or bool, number, etc...
})
}
resource "null_resource" {
triggers = {
some_name = var.foo.name
some_id = var.foo.id
some_foobar = var.foo.foobar
}
} ... and then call it, explicitly setting the optional properties to
module "potato" {
source = "./modules/myfoo"
foo = {
name = "something-cool-is-afoot"
id = 1234567890
foobar = null
}
} This allows you to do normal stuff like set defaults using a ternary check, eg.:
|
Along the same lines, it would be useful to be able to declare partial defaults for complex types For instance, something like variable "with_default_path" {
type = object({
id = string
path = string
})
default = {
path = "/"
}
} |
Hi folks! This is a great feature request, and getting use-cases is absolutely helpful, but so you know it best to react to the original issue comment with 👍which we can and do report on during prioritization. |
Absolutely, this should be part of the original post as well 👍 Optional values |
@solsglasses - please add reactions to comments, pull requests, or issues instead of creating a new comment simply to show agreement with someone. Thanks for helping to keep the community awesome, and the notification feed of -- well, everyone -- free of fluff! |
I'm not sure of the internals, but this may not be that difficult. Since type and defaults are already well defined, the parser would just need to allow both of them and then merge the defaults with the provided variable before validation. My proposal mostly dealt with optional values inside the type definition, not the argument itself being optional. The might get a little trickier. Having the argument be optional is going to lead to a lot of lines like:
It may make more sense for the It could reduce a bunch of boilerplate code if there was an |
Update: I created #22449 to track this. One more proposal to add to the mix:
I think would allow more readable complex object definitions in cases where defaults could appear at any level, and would have parity with how defaults in
(the use-case for having both |
For what it's worth, even the minimal behavior (accepting objects with omitted values and setting the omitted values to null) would be a major usability improvement. Defaults could be implemented within modules themselves. |
Very needed possibility for maps and objects types. |
Being able to set a |
My personal vote is also to add support for default values, rather than support for marking some fields as optional. Defaults imply optionality, so you get optionals for free by supporting defaults. OTOH, if we add |
Definitely @atavakoliyext proposal is best. @prehor thefotios proposal:
Why we cannot use it:
|
Actually there are workarounds for optional arguments in object variables. The tricky part is still on the default value of the variable and using local variables. Use the locals variable to verify the optional parameter in "network_rules". Put it into null if not existing. The other resources would be able to refer to those local variables.
|
@lemontreeran This does not work. I cleaned up your example:
And provided a terraform.tfvars like so:
The result:
You cannot have optional elements of a well-defined variable object. |
Try adding the null value for those vars. I know it is ugly......
|
It's not that it is ugly, it is not optional if you have to supply a value, which is the whole point of this issue. |
@grimm26 Yes, that is why the issue is still open. As @lemontreeran noted, and as I wrote earlier in the thread, providing |
Or following the first post, I'd like to pass default values like this: variable "network_rules" {
default = null
type = object({
bypass = optional(list(string), ["teste"])
ip_rules = optional(list(string), null)
virtual_network_subnet_ids = optional(list(string), [])
enabled = optional(bool, true)
})
} The |
Where we have a map or list of map the solution should include the capability for the map key to be absent.
so if bar is not provided by the caller the key would be completely absent. this way you can use the absence of the key to infer some more complex default action rather than having to use a rouge value for default. |
You need to be on at least v0.14 |
Another 2022 bump on this, would definitely need it in my map of object setup where I don't want advanced options to be mandatory. |
I find the separate declaration of the types and the defaults a bit cumbersome and the "optional" keyword superfluous. I think this has already been suggested, but the syntax for declaring the attributes of a variable is already defined, so it would be consistent to just make them recursive, eg.
|
I was surprised that when specifying an object as a type it filters out all inputs that aren't declared. I love all the ideas about specifying optional variables and stuff... but this has been open for 4 years. Maybe just don't kill things not declared in the type, then give us the awesome later? tfvars:
variable:
outputs:
In my opinion this should either error or let |
I prefer to have them declared explicitly. This way you can look at the type declaration and see which fields are supported. |
It also means that the language server ( |
Me too... but the five stages of grief are "denial, anger, bargaining, depression and acceptance" and right now I'm at the bargaining stage. If I can't have something perfect, can I at least have something less nice? |
I'm at the bargaining phase myself. Simply getting rid of the "experimental" warning would please me. |
For me this has been experimental for how long, I just would like to know what is the reason, what is causing issues, and is it really something that should be a blocker versus a hey every FYI this WILL break if you do this you know it will break. |
@apparentlymart Can we get an ETA (or declaration of lack of interest in an ETA) for taking this feature out of
|
Hi all, Based on feedback about the existing experiment, we don't intend to graduate it to be a stable feature exactly as currently designed. Instead, we intend to make another design iteration which better integrates the idea of default values into the constraints system, and deals with some other concerns that folks raised in feedback on the existing proposal. We don't intend to take the experiment away until there's a new experiment to replace it, but if you do wish to use it in production in spite of its experimental status I suggest keeping in mind that you will probably need to change your configuration at least a little in response to the changes for the second round of experiment. The purpose of experiments is to gather feedback before finalizing a design, so in this case the experiment process worked as intended but since the feedback led to us needing another round of design we had to wait until there was time to spend on that design work, since the team was already wholly assigned to other work. We'll share more here when there's more to share. |
Flagging #30608 as a related enhancement request that might merit consideration for future state consistency when refactoring of the optional arguments stuff here. |
It seems like long-term, to enforce types in a way that works for reasonable use cases, following in the pattern of TypeScript could be extremely useful. Let's say there are two properties that are mutually exclusive. Even with optional(), there's no way to express with the type system that either ONE or the OTHER must be present—that would have to be a validation error that occurs at runtime instead of giving an error at design time. Here's a concrete example of a real use-case for creating AWS CloudWatch dashboard widget JSON: properties
But TypeScript handles this with type unions. That might look something like this:
Using something like this would avoid the need for validation to enforce the mutual exclusivity, allowing the type system itself to represent the strict expected types and the either/or nature of both |
Looks like this is happening with TF v1.3.0. https://github.com/hashicorp/terraform/releases/tag/v1.3.0-alpha20220608 |
@fabiendelpierre You beat me to it :) Hi all, we'd love your feedback on the latest v1.3 alpha, which includes the ability to mark object type attributes as optional and set default values. You can learn more/provide feedback here. Thank you in advance! |
Further to my previous post, I would suggest that (though the v1.3.0 adding of the 2nd default field in the "optional()" function is an improvement) the "optional()" keyword/function itself is really a bit of a red-herring and simply expanding the variable structure to allow nesting would be a more natural and syntactically consistent approach. A simple variable declaration:
A complex variable declaration:
Just as with normal variables, the act of declaring a default makes it optional; there is no need for an "optional()" keyword/function and conversely not specifying a "default" makes it a required item. Thinking about it, the "object()" declaration could become redundant too, as the fact that there is a mix of types would implicitly make that so.
Extrapolating that further, the "type =" lines could be recursive and thus support sub-objects . |
@prowlaiii is what you're describing similar to the feature request in #22449? |
I think it is indeed; I hadn't seen it, but I knew I couldn't have been the first person on the planet to think of it! (I'm also suggesting the "description =" item and removing the need for "object()" there.) FYI, I also raised this in the v1.3 feedback and have now included a link to yours there. |
If we're going to take it that far then why not just go all the way and create a new type that lets you simply specify an openapi schema? The openapi shema variable type could be defined inline, sourced from a file in the same directory, or maybe even from a remote source (like we source modules today). That capability would make it easy to create, document, and reuse complex data classes in our input and output blocks. |
Hi all, An evolution of the optional attributes experiment, with built-in support for default values and no separate For that reason, I'm going to close this issue to represent that the base use-case is met. I see that there is some discussion here about further additions to the model for object attributes, but I think it'll be better to discuss those in more specific issues once the initial features are included in a stable release and we can learn from experiences of using the first iteration of this functionality in a broad set of Terraform modules with differing design needs. Thanks for the great discussion here! |
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. |
Current Terraform Version
Proposal
I like the
object
variable type and it would be nice to be able to define optional arguments which can carrynull
value too, to use:instead of:
The text was updated successfully, but these errors were encountered: