-
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
Logical binary operators don't short-circuit #24128
Comments
This is doubly confusing as Work-around is to use the conditional edit: coalesce and coalescelist can also be used for working around this |
I have attempted a conditional expression for a work-around but it seems aggressively wordy when trying to handle the case "is not null and is not empty list"
I find this preferred syntax otherwise throws error "argument must not be null" when
Is there a better way (prior to widespread adoption of variable validation)? |
@jeliker you can write those a bit more clear with
|
Well, this came as a bit of a shock today. I've always assumed that logical operators in Terraform were short-circuiting, much like they are in Java or Go. Although functions like In cases like @jeliker's I had to replace this: # var.rules is a map(object(...))
rules_provided = var.rules != null && length(var.rules) > 0 ...with this: rules_provided = length(var.rules != null ? var.rules : {}) > 0 So @jeliker , your expression can be simplified to: image_ids = length(var.image_ids != null ? var.image_ids : []) == 0 ? var.default_ids : var.image_ids ...which is still somewhat ugly and less readable than a logical operator. |
Thank you for your comments @sergei-ivanov. Seems I have this pattern:
…and you have this pattern
...so we are forced to evaluate twice in any case. Hopefully this will resolve to more expected (in my opinion and evidently yours, perhaps others) short-circuit behavior soon |
@jeliker Yes, it is only about grouping. I also wish that the problem is eventually fixed at source (in Terraform). |
Hi all! It does seem reasonable to support a short-circuit behavior for the logical operators in the Terraform language. These operators are actually implemented upstream in the HCL library, which is why this was previously labelled as "dependencies". Because implementing this represents a change in the behavior of HCL and HCL is used in other codebases apart from Terraform it will require some coordination to implement, although I think it should be safe to implement in a minor release because the change in behavior is a positive one: expressions that would previously have failed with an error will now succeed in some way, and no expressions that would previously have succeeded will start producing a new value or start returning an error. |
Just ran into this myself doing |
In lieu of HCL changes to the operators themselves, could we get lazy evaluating |
We already have |
The ternary operator does however, (as long as you know the type I suppose) thanks for that suggestion.
|
Just ran into this with |
Including a note about logical operators not short-circuiting will make the documentation clearer and more useful. hashicorp#24128 includes examples of people being caught out by this lack of clarity.
Including a note about logical operators not short-circuiting will make the documentation clearer and more useful. hashicorp/terraform#24128 includes examples of people being caught out by this lack of clarity.
Including a note about logical operators not short-circuiting will make the documentation clearer and more useful. hashicorp/terraform#24128 includes examples of people being caught out by this lack of clarity.
Including a note about logical operators not short-circuiting will make the documentation clearer and more useful. hashicorp/terraform#24128 includes examples of people being caught out by this lack of clarity.
Logical binary operators don't short-circuit: hashicorp/terraform#24128
Logical binary operators don't short-circuit: hashicorp/terraform#24128
Logical binary operators don't short-circuit: hashicorp/terraform#24128
Is there a ticket tracking the upstream work for this in the HCL library? I couldn't see one when I searched: |
It is beyond understanding that such a fundamental language construct is not properly implemented .... So instead of writing An example of validation code that we are producing right now precondition {
condition = local.dnat != null ? try(local.dnat.rules, null) != null ? alltrue([for rule in local.dnat.rules: (try(rule.translated,null) != null ? try(rule.translated.value, null) != null ? rule.translated.value != "" : false: true) ]) : true: true
error_message = "'local.dnat.rules[*].translated.value' should not be null or blank"
} It sure works fine but this code is not maintainable in the long term |
We've come up with a workaround for another edgecase. The logic:
The implementation: variable "credential_id" {
type = string
default = null
}
data "lastpass_secret" "credential" {
for_each = var.credential_id != null ? { enabled = true } : {}
id = var.credential_id
}
locals {
default_credential = {
username = "provisioner",
password = null # rely on ssh-agent for auth
}
credential = merge(
{ enabled = local.default_credential },
data.lastpass_secret.credential
)["enabled"]
} The I'm positing this because our initial attempt was to use ternary operator return either data resource or default object but it wouldn't work when data resource wasn't created because ternary short-circuits "too late" if at all. now that I think about it it's just a variant of |
@apparentlymart - this issue has been around for a while now. Any idea what the current status of this feature is? Thanks! |
I believe this was examined in hashicorp/hcl#538, although not completed. |
Just bumped into this too. This is how we resolved it for anyone interested (this example is more complicated due to the optional nature of the offending variable):
The |
This comment was marked as off-topic.
This comment was marked as off-topic.
Since this is a now documented behaviour as per he merge of this then, shouldn't this have now been closed? |
@mloskot No, because it is labelled 'enhancement', not 'bug' or 'missing docs' or something. (By a maintainer, with #24128 (comment) on intention, and draft PR hashicorp/hcl#538.) |
Yes, but the label pre-dates the #30631, so it could be the case the label no longer applies
I have missed the draft. Thanks. |
Terraform Version
Terraform Configuration Files
Crash Output
Error: Invalid index
on ....\az-terraform-diagnostic-settings\module.tf line 12, in locals:
12: bln_use_datasrc = (length(value.log) > 0) && (lower(value.log[0][0]) == "alllogs")
|----------------
| value.log is empty list of tuple
The given key does not identify an element in this collection value.
Expected Behavior
If the variable log value in empty, the Length(log) > 0 shoudl return false and lower(value.log[0][0]) == "sdsds") should not have executed
Actual Behavior
eventhough the Length(log) > 0 is false, and short circuite is not happening and ower(value.log[0][0]) gets executed.
Steps to Reproduce
Additional Context
References
The text was updated successfully, but these errors were encountered: