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

only evaluate the part of a ternary statement that is used #11574

Closed
dansteen opened this issue Jan 31, 2017 · 11 comments
Closed

only evaluate the part of a ternary statement that is used #11574

dansteen opened this issue Jan 31, 2017 · 11 comments

Comments

@dansteen
Copy link

dansteen commented Jan 31, 2017

Terraform Version

0.8.5

Affected Resource(s)

not a specific reasource, but rather the way ternary operations are processed

Terraform Configuration Files

# we only build the the sns topics if the sns_env is the same as the env
resource "aws_sns_topic" "api" {
  count = "${var.env == var.sns_env ? 1 : 0}"
  name = "${var.name}-${var.env}"
}

resource "consul_keys" "api" {
  token = "${var.consul_token}"
  # host url
  key {
    delete = "true"
    path  = "service/app/${var.name}/${var.env}"
    value = "${var.env == var.sns_env ? "${aws_sns_topic.api.arn}" : "none" }"
  }

Expected Behavior

I would expect it not to attempt to evaluate ${aws_sns_topic.api.arn} in a case where var.env != var.sns_env. That way, if that resource is not created things will still work.

Actual Behavior

Instead it attempts to evaluate both parts of the ternary results, and I get the following error in a case where var.env != var.sns_env:

* consul_keys.api_sns: resource count can't reference resource variable: aws_sns_topic.api.arn

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply

Thanks!

@osterman
Copy link

osterman commented May 5, 2017

I have this problem as well... We use count to enable/disable a resource. Unfortunately, it's not working. This snippet is taken from a null_resource.trigger:

green_arn_1 = "${aws_elasticsearch_domain.search.count > 0 ? aws_elasticsearch_domain.search.arn : ""}"

Error:

* null_resource.search: Resource 'aws_elasticsearch_domain.search' not found for variable 'aws_elasticsearch_domain.search.arn'

@dayglojesus
Copy link

Obligatory me too post...

We began using this for an AMI auto-select feature in 0.8.4 and discovered this behaviour after upgrading to 0.9.5.

variable "ami" {
  default = ""
}

data "aws_ami" "current_ami" {
  most_recent = true

  filter {
    name   = "tag:os"
    values = ["centos"]
  }

  owners = ["self"]
}

resource "aws_instance" "test" {

  ami = "${var.ami == "" ? data.aws_ami.current_ami.id : var.ami}"

}

Results in:

1 error(s) occurred:

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

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

${var.ami == "" ? data.aws_ami.current_ami.id : var.ami}

It's a bit of a showstopper for us.

@apparentlymart
Copy link
Contributor

@dayglojesus in your case I think you are seeing #14399 rather than this issue. That was just a straight regression in the latest release, and a fix is ready for the next release.

@dayglojesus
Copy link

@apparentlymart ah, good to know. thanks!

@hroussez
Copy link

hroussez commented Nov 1, 2017

I'm running into a similar issue. My code looks like:

variable "enabled" {
  default = false
}

resource "aws_lb" "main" {
  ...
}

resource "aws_lb" "extra" {
  count = "${var.enabled}"
  ...
}

output "extra_dns_name" {
  value = "${var.enabled ? aws_lb.extra.dns_name : aws_lb.main.dns_name}"
}

I get the following error:

* output.extra_dns_name: Resource 'aws_lb.extra' not found for variable 'aws_lb.extra.dns_name'

Should I be doing it differently, or should we work on this issue?

EDIT: I found a related issue/workaround here: #2831 (comment)

@fractos
Copy link
Contributor

fractos commented Nov 9, 2017

Just hit this too... massively annoying. (0.9.10 and 0.10.3). Modified from the original code but it demonstrates the point:

data "aws_db_instance" "mydb" {
  count                  = "${var.use_db == true ? 1 : 0}"
  db_instance_identifier = "db-whatever"
}

data "template_file" "task_worker" {
  template = "${file("./task-definitions/worker.jsontemplate")}"

  vars {
    database_host            = "${var.use_db == true ? data.aws_db_instance.mydb.address : ""}"
  }
}

gives

Error running plan: 1 error(s) occurred:

* data.template_file.task_worker: 1 error(s) occurred:

* data.template_file.task_worker: Resource 'data.aws_db_instance.mydb' not found for variable 'data.aws_db_instance.mydb.address'

@JoseIbanez
Copy link

Just tested in v0.10.8 for a counter:

resource "aws_route" "route-n" {
  count                   = "${length(var.nfvs)}"
  route_table_id          = "${aws_route_table.RT_OUT.*.id[count.index]}"
  destination_cidr_block  = "99.99.0.1/32"
  network_interface_id    = "${count.index + 1  < length(var.nfvs) ? aws_network_interface.eni_OUT.*.id[count.index+1] : aws_network_interface.RO_eni_OUT.id }"
}

i get this error:

Error: Error running plan: 1 error(s) occurred:
* aws_route.route-n: 1 error(s) occurred:
* aws_route.route-n[1]: index 2 out of range for list aws_network_interface.eni_OUT.*.id (max 2) in:
${count.index + 1  < length(var.nfvs) ? aws_network_interface.eni_OUT.*.id[count.index+1] : aws_network_interface.RO_eni_OUT.id }

@m4ce
Copy link

m4ce commented Jan 8, 2018

Same problem here with index out of range ... had to switch back to element()

@apparentlymart
Copy link
Contributor

Hi @dansteen, and everyone else here! Sorry about this limitation and thanks for reporting it.

This is the same issue being discussed in #11566. As mentioned there, a new version of the interpolation evaluator is coming which fixes this and many other limitations. Since we already have that issue open I'm going to close this one just to consolidate the discussion over there. That issue also contains some example workarounds for certain situations, which may be useful in the short term.

@s2504s
Copy link

s2504s commented Feb 14, 2018

As workaround I use method join for resource which is presented as an array *

resource "aws_sns_topic" "api" {
  count = "${var.env == var.sns_env ? 1 : 0}"
  name = "${var.name}-${var.env}"
}
If using:
resource "consul_keys" "api" {
  token = "${var.consul_token}"
  # host url
  key {
    delete = "true"
    path  = "service/app/${var.name}/${var.env}"
    value = "${var.env == var.sns_env ? "${join("", aws_sns_topic.api.*.arn)}" : "none" }"
  }

@ghost
Copy link

ghost commented Apr 3, 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 3, 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