-
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
In an unknown choice of 1 of 2 lists, if the lists are the same length, the list length should be known #33237
Comments
Thanks for reporting this, @Nuru! Terraform is behaving as designed here -- the documentation never promised that the conditional operator would produce anything other than an unknown value when the predicate is itself unknown -- so I'm going to relabel this as an enhancement to reflect that supporting what you've described requires changing Terraform's design to treat unknown values differently and make additional promises about them. However, it's good timing that today I opened #33234 which introduces the initial building blocks required to solve this: the possibility for an unknown list to have bounds on its length, including possibly having its lower bound and upper bound equal which then allows it to become a known list with all elements unknown instead. That PR doesn't include a change to the conditional operator to achieve exactly what you called for here, but I mentioned in that PR that I have a commit for HCL to teach its various operators to refine their outputs, and I already implemented a rule in that commit so that if a conditional operator is choosing between two different values of the same collection type then it'll refine an unknown result to have length bounds set to the range between the true and the false expression. If the true and false expression are both known to have the same length then that will allow the result to become a known list with all elements unknown, just as you described here. (In order for this to work out as I described you'd need to make sure your condition actually returns a list type and not a tuple type, so it might be necessary to add one or to With that said then: I think we already know what needs to happen to make Terraform behave as you described, but it's a pretty big set of changes so we'll need to review and merge them carefully. Once we get to the point where I'm opening a PR to introduce the HCL-side changes into Terraform I'll mark that PR as closing this issue. Thanks again! |
I've now opened #33294 with the HCL update I mentioned. As I suspected before, it was necessary to explicitly tell Terraform that the conditional expression should return a list in order to activate the new behavior, so I've modified the conditional to use variable "bug" {
type = bool
description = "set to true to trigger the bug"
default = true
}
resource "random_integer" "coin" {
max = 2
min = 1
}
locals {
coin_flip = random_integer.coin.result > 1
rules = [
{
list = (var.bug ? local.coin_flip : true) ? tolist([null]) : tolist([null])
description = "example description"
}
]
# Use concat to flatten the list of lists into a single list
# instead of flatten because flatten depends on values.
expanded_rules = concat(concat([[]], [for n, rule in local.rules : [for i, v in rule.list : {
key = "exp.${n}.${i}"
description = rule.description
item = "known" // In useful code, this would be `v`
}]])...)
keyed_rules = { for rule in local.expanded_rules : rule.key => rule }
}
resource "null_resource" "count" {
count = length(local.keyed_rules)
triggers = {
description = values(local.keyed_rules)[count.index].description
}
}
resource "null_resource" "for_each" {
for_each = local.keyed_rules
triggers = {
description = each.value.description
}
} Without that change, we can see the unknown value error as reported:
With the new HCL changes included, it successfully completes planning with a known list whose elements are all unknown:
I expect that more improvements in this area will follow later on, now that we have this new "refinements" primitive to work with, but for now there's at least one way to make this work as described. |
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
Of course this is very pared down from useful code:
bug.tf
Debug Output
n/a
Expected Behavior
Terraform should be able to plan
Actual Behavior
The dreaded
count
andfor_each
errors:Click to see Error Message
The unknown value of
local.rules[0].list
should not make it a list of unknown length, because both options are the same length, but it does.Steps to Reproduce
terraform init
terraform plan -var bug=false
# succeedsterraform plan -var bug=true
# failsAdditional Context
This is part of the ongoing saga of not being able to use
count
orfor_each
because of derived values not known at plan time.References
Originally posted by @apparentlymart in #26755 (comment)
At first I thought that the unknown value of
local.rules[0].list
was making the other attributes in the object unknown. However, replacingwith
allows the plan to succeed, which indicates the problem is with the length of the list.
The text was updated successfully, but these errors were encountered: