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

Looks like True and False expression types should not match in all cases? #14399

Closed
andrey-iliyov opened this issue May 11, 2017 · 10 comments · Fixed by #14454
Closed

Looks like True and False expression types should not match in all cases? #14399

andrey-iliyov opened this issue May 11, 2017 · 10 comments · Fixed by #14454

Comments

@andrey-iliyov
Copy link

Terraform Version

Terraform v0.9.5

Affected Resource(s)

  • aws_instance

Terraform Configuration Files

resource "aws_instance" "test_instance_record" {
  ...
  ami = "${var.test_consul_ami ? var.aws_ami : data.consul_keys.test_consul_ami.var.ami}"
  ...
}

data "consul_keys" "test_consul_ami" {
  key {
    name    = "ami"
    path    = "xx-xxx/yy-yyy"
    default = "ami-xxxxxxxx"
  }
}

Expected Behavior

Should works. It works if I use Terraform v0.9.4

Actual Behavior

1 error(s) occurred:

* aws_instance.test_instance_record: 1 error(s) occurred:

* aws_instance.test_instance_record: At column 3, line 1: true and false expression types must match; have type string and type unknown in:

${var.test_consul_ami ? var.aws_ami : data.consul_keys.test_consul_ami.var.ami}

Steps to Reproduce

  1. terraform plan

Additional info.

Just for test I used the same expression types for true and false:
It will works If I will change ami to:

ami = "${var.test_consul_ami ? data.consul_keys.test_consul_ami.var.ami : data.consul_keys.test_consul_ami.var.ami}"

or

ami = "${var.test_consul_ami ? var.aws_ami : var.aws_ami}"
@pikeas
Copy link
Contributor

pikeas commented May 11, 2017

Happening for me as well with:

${var.use_instance_profiles ? aws_iam_instance_profile.aws.name : ""}

@daaru00
Copy link

daaru00 commented May 12, 2017

+1

@daveadams
Copy link
Contributor

If you need other examples, I have the same problem with:

${var.hostname != "" ? data.template_file.hostname.rendered : "" }

@bhuisgen
Copy link

Same problem here :

* module.test.aws_eip.haproxy: At column 3, line 1: true and false expression types must match; have type unknown and type int in:

${var.internal == "no" ? aws_instance.haproxy.count : 0}

@dthagard
Copy link
Contributor

dthagard commented May 12, 2017

Is this error related to this commit? 0e963db

Trace log shows the following interesting bits:

2017/05/12 11:14:43 [TRACE] [walkValidate] Entering eval tree: module.mymodule.module.mymodule.module.cloudfront.var.waf_acl_id
2017/05/12 11:14:43 [DEBUG] root.mymodule.mymodule: eval: *terraform.EvalSequence
2017/05/12 11:14:43 [DEBUG] root.mymodule.mymodule: eval: *terraform.EvalInterpolate
2017/05/12 11:14:43 [ERROR] root.mymodule.mymodule: eval: *terraform.EvalInterpolate, err: At column 3, line 1: true and false expression types must match; have type unknown and type string in:

${var.waf_acl_id == "" ? module.waf.waf_elb_id : var.waf_acl_id}
2017/05/12 11:14:43 [ERROR] root.mymodule.mymodule: eval: *terraform.EvalSequence, err: At column 3, line 1: true and false expression types must match; have type unknown and type string in:

${var.waf_acl_id == "" ? module.waf.waf_elb_id : var.waf_acl_id}
2017/05/12 11:14:43 [TRACE] [walkValidate] Exiting eval tree: module.mymodule.module.mymodule.module.cloudfront.var.waf_acl_id

@apparentlymart
Copy link
Contributor

I think this is some fallout from #14135. We're missing the special case of making the conditional return unknown ("computed", to use the terminology from the UI) if either one of its values is unknown, so we're falling through to the usual type check, which then produces this error.

@apparentlymart apparentlymart self-assigned this May 12, 2017
apparentlymart added a commit to hashicorp/hil that referenced this issue May 12, 2017
In #52 we relaxed the rule that any unknown value would immediately cause
an early exit, which in turn requires the type checker for each node to
specifically deal with unknown values.

However, we missed dealing with the check that both types match in a
conditional, causing a conditional to fail if either side of it is
unknown.

This causes errors in Terraform, as described in
hashicorp/terraform#14399.
apparentlymart added a commit that referenced this issue May 12, 2017
hashicorp/hil#53 addresses a regression with type checking of unknown
values in the HIL conditional operator.

This fixes #14399.
@apparentlymart
Copy link
Contributor

Hi all! Sorry for this regression.

I have opened #14454 to merge in the upstream fix from the interpolation language parser that should clear this up.

Until this gets merged and released, a workaround is to use a -target argument to make Terraform create in isolation the resource whose computed attribute is being used in the conditional.

So in @pikeas's case, for example, this might be:

terraform plan -out=tfplan -target="aws_iam_instance_profile.aws.name"
terraform apply tfplan

Once the resource has been created its computed attributes will be known and so Terraform should then be able to evaluate the conditional expression as expected.

apparentlymart added a commit that referenced this issue May 12, 2017
hashicorp/hil#53 addresses a regression with type checking of unknown
values in the HIL conditional operator.

This fixes #14399.
@wr0ngway
Copy link

Also seeing this on 0.9.5 when using a conditional with a rendered template as one branch and literal string as the other. Work around, wrap the rendered template with format to force a string type
${var.foo == "" ? format("%s", data.template_file.bar.rendered) : ""}

@apparentlymart
Copy link
Contributor

Ahh, good idea on that workaround, @wr0ngway! Any function that returns a string should work similarly.

This is now merged, so we'll get this fixed properly in 0.9.6. The -target workaround I mentioned above should work as a one-off for configurations that you just want to spin up once and leave running for a long time, but this trick of using a string function to fool the type checker is a good way to do it for configs that you need to create/destroy a lot, where that extra -target step would be more inconvenient.

@ghost
Copy link

ghost commented Apr 12, 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 Apr 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants