Skip to content
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

Interpolation should only evaluate one branch of a condition #15605

Closed
Kentzo opened this issue Jul 21, 2017 · 13 comments
Closed

Interpolation should only evaluate one branch of a condition #15605

Kentzo opened this issue Jul 21, 2017 · 13 comments
Milestone

Comments

@Kentzo
Copy link

Kentzo commented Jul 21, 2017

Conditionals are handy, but it looks like both branches are always evaluated.

My specific use case is that I want to have a variable that may or may not point to a file:

# variables.tf

variable "file_path" {
  default = ""
}

# main.tf

data "template_file" "template" {
  vars {
    file_contents = "${length(var.file_path) > 0 ? file("${var.file_path}") : ""}"
  }
}

However I always get the "file: open : no such file or directory in:" error, even if I change conditional to:

"${false ? file("${var.file_path}") : ""}"
@rorybrowne
Copy link

rorybrowne commented Jul 24, 2017

This is a known issue with Terraform. The main workaround so far seems to be to find something to put in each branch that will run without error.

For example in what you describe you may be able to do something like this:

"${truthtest ? file("${truthtest ? var.file_path : "/dev/null"}") : ""}

Or since file("/dev/null") should equal "" just:

file("${truthtest ? var.file_path : "/dev/null"}")

hashicorp/hil#50

@apparentlymart
Copy link
Contributor

Indeed, this is something we know about and are planning to solve as part of a suite of changes to the configuration language that will come in a future release.

Sorry for the weirdness here; we had the choice of postponing adding the conditional altogether or releasing it in a partially-functional state, and we decided to go with the latter so that certain use-cases could be met in the mean time while we work on the architecture of the interpolation language interpreter so that it can support conditionals fully-generally.

Although we already have that HIL issue open, I'm going to leave this issue here as a marker for the issue from Terraform's perspective, since I expect most people looking for this issue won't know to look for it in the HIL repository.

@Kentzo
Copy link
Author

Kentzo commented Jul 24, 2017

@rorybrowne Thank you for the workaround, it works.

@apparentlymart Looking forward to a solution.

@olenm
Copy link

olenm commented Sep 21, 2017

EDIT: got a workaround from the hashicorp/hil#50 as mentioned in issue #15912

I believe I am encountering this but with (nested) modules.
example:

  • I have a module to bring up an instance + security group (lets call this Mod-A) with an "enable" variable (converted into count = 0/1 with conditionals)
  • another module (Mod-B) that creates two Mod-A
  • tf file that creates Mod-B with outputs for each Mod-A's instance (with a state, enabled or disabled)
  • output is completely skipped for anything referencing a Mod-A that is disabled

I have even set both modules (Mod-A and Mod-B) to use conditionals in the output, to output "" when it is disabled and the actual instance_id otherwise.

This is not only for output block either, my main goal was to use the instance_id and associate it into an EIP.

Any suggestions of a workaround (or would a poc set of files be needed in this case)?

Edit: thought I had a workaround where enabling both then removing one, as the old state was yanked, but another tf plan/apply proved me wrong (I have to workaround)

@dan-rose
Copy link

If any one can help then we hit this error too -

name_prefix = "${length(var.customer_name) < 5 ? "${var.customer_name}-" : "${substr(var.customer_name, 0, 5)}-"}"

substr: 'offset + length' cannot be larger than the length of the string

@rafalcieslak
Copy link

@dan-rose You should be able to work around that with:

name_prefix = "${substr(var.customer_name, 0, min(length(var.customer_name), 5))}-"

@dan-rose
Copy link

It works! I think I love you x

@jl2501
Copy link

jl2501 commented Jun 8, 2018

Would love to see this fix pushed out. The company I work for has some of our infra inside of a third-party hosted account for some security compliance purposes. Long story short, because of that, combined with this TF issue I currently have to create a separate set of TF modules for everything that has to end up going into that account.

Is there an ETA for a fix? I understand that this is not a simple fix for you, I'm just trying to guess how long I have to do things this way before a fix for this becomes available.

Thank you.

@arturo-aparicio
Copy link

Is there any progress in this? The workarounds suggested work in some cases but they look ugly and are not intuitive when reading.

@apparentlymart
Copy link
Contributor

This problem will be addressed in the next major release of Terraform.

@apparentlymart
Copy link
Contributor

Hi all! Sorry for the long silence here.

I've just verified that this is now working correctly in v0.12.0-alpha1, using a simple test case in terraform console for simplicity:

$ terraform console
> false ? file("nonexist") : "it was false"
it was false

> true ? file("nonexist") : "it was false"

Error: Error in function call

  on <console-input> line 1:
  (source code not available)

Call to function "file" failed: no file exists at nonexist.

As expected, it now returns errors only from the side of the conditional expression that is evaluated.

This fix is in master and will be included in the v0.12.0 final release, once the prerelease cycle is completed. Because of that, I'm going to close this out. Thanks for reporting this, and thanks for your patience while we laid the groundwork to fix it.

@gurpreetatwal
Copy link

It seems like this issue still shows up if any of the branches reference a terraform resource. I apologize if this the wrong thread to comment on or if the issue of conditional resource references is being tracked elsewhere, I wasn't able to find an open issue tracking that.

The following code fails on Terraform v0.12.23

$ terraform console
> true ? aws_security_group.test : null

>
Error: Reference to undeclared resource

  on <console-input> line 1:
  (source code not available)

A managed resource "aws_security_group" "test" has not been declared in the
root module.

@ghost
Copy link

ghost commented Mar 13, 2020

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.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Mar 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants