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

core: allow non-computed data source values in "count" #11482

Merged
merged 5 commits into from
Jan 30, 2017

Conversation

mitchellh
Copy link
Contributor

@mitchellh mitchellh commented Jan 28, 2017

Based on #10418, but simpler due to new graphs (more LOC change due to tests).

This disables the computed value check for count during the validation
pass. This enables partial support for #3888 or #1497: as long as the
value is non-computed during the plan, complex values will work in
counts.

Notably, this allows data source values to be present in counts!

The "count" value can be disabled during validation safely because we
can treat it as if any field that uses count.index is computed for
validation. We then validate a single instance (as if count = 1) just
to make sure all required fields are set.

This still won't allow "computed" data source values: data sources that
themselves depend on the value of some computed resource (non-data source).

As promised, this loosens the strict requirement of computed count values.
I'm still trying to make this even better for 0.9...

This disables the computed value check for `count` during the validation
pass. This enables partial support for #3888 or #1497: as long as the
value is non-computed during the plan, complex values will work in
counts.

**Notably, this allows data source values to be present in counts!**

The "count" value can be disabled during validation safely because we
can treat it as if any field that uses `count.index` is computed for
validation. We then validate a single instance (as if `count = 1`) just
to make sure all required fields are set.
@myoung34
Copy link
Contributor

@mitchellh will this have any effect on #7034 ? namely inline settings blocks such as

   setting {
     count = "${var.spin_down_at_night == "true" ? 1 : 0}"
     namespace = "aws:autoscaling:scheduledaction"
     resource = "ScheduledPeriodicScaleup"
     name = "Recurrence"
     value = "0 10 * * *" #10am UTC = 4am CST
   }

@mitchellh
Copy link
Contributor Author

@myoung34 Zero effect for or against, we'd like to support that though.

@myoung34
Copy link
Contributor

Thanks for the quick reply. Too bad, but at least it's not a "no"

@odupuy
Copy link

odupuy commented Jan 30, 2017

Can you give an example of what becomes doable with this fix?

@mitchellh
Copy link
Contributor Author

mitchellh commented Jan 30, 2017

@odupuy here is an abstract example:

data "foo" "bar" {}
resource "baz" "qux" { count = "${data.foo.bar.value}" }

More concrete examples just in human words since I don't know their exact syntax/attributes: reading a Consul key to get the count, reading data about an AWS instance and using that for count, etc.

EDIT: Here is what I mean by "non-computed data source", this won't work:

data "foo" "bar" {
  attr = "${aws_instance.foo.id}"
}

resource "baz qux" { count = "${data.foo.bar.value}" }

Because the data source in the above case relies on a non-data source, it can't be loaded until apply-time, meaning it is computed. Data sources that don't rely on non-data sources (transitively) are loaded before that.

@RichardBronosky
Copy link

I just discovered that deterministic math is acceptable even though count must be "non-computed".

https://gist.github.com/RichardBronosky/9ba397e85e4af86e517b33af32ad8706

@mitchellh
Copy link
Contributor Author

@RichardBronosky that is non-computed! I meant in the Terraform definition of the word "computed", which is: value cannot be determined until apply-time (outputs of to-be-changed resources basically).

@thatderek
Copy link

thatderek commented Jan 31, 2017

Another example for this is setting up a subnet in every availability-zone, regardless of which region you're executing a plan in. A la:

data "aws_availability_zones" "available" {}

resource "aws_subnet" "public" {
  count = "${length(data.aws_availability_zones.available.id)}"

  availability_zone = "${data.aws_availability_zones.available.id[count.index]}"
}

whereas before my subnetting module had a integer variable with a default value (of three), and I had to have extensive explanations in my README about what defaults to change for regions with only 2 AZs.

Thanks @mitchellh ! This fixes a problem I ran into weekly and makes modules much more powerful!

@kojiromike
Copy link

For a slightly more concrete example, I'm (expecting) to be able to do this:

data "template_file" "cname" {
  template = "/dev/null"

  vars {
    count = "${1 + length(var.additional_cnames)}"
    primary = "${join("-", compact(list(var.customer, var.environment == "prod" ? "" : var.environment)))}"
  }
}

resource "null_resource" "cname" {
  count = "${data.template_file.cname.vars.count}"
  triggers {
    value = "${count.index == 0 ? data.template_file.cname.vars.primary : element(var.additional_cnames, 1 + count.index)}"
  }
}

resource "aws_route53_record" "cname" {
  count = "${data.template_file.cname.vars.count}"
  name    = "${element(null_resource.cname.*.triggers.value, count.index)}"
  records = ["${aws_instance.ngnx.public_dns}"]
  ttl     = "60"
  type    = "CNAME"
  zone_id = "${data.terraform_remote_state.base.my_zone_id}"
}

@mitchellh
Copy link
Contributor Author

@kojiromike looking at that, I believe that'll work.

@greenboxal
Copy link

Awesome! What are your plans on computed counts?

I'm using the changes that I made on #10418 and I have one issue when creating new resources with computed resource counts.

Basically I need to run apply two times: On the first it creates one resource (assumes count = 1, as in validation). In the second, it creates the resources correctly as the dependencies are resolved in the state.

@apparentlymart
Copy link
Contributor

@greenboxal I think you're describing something like what was discussed in #4149. That's a more complete solution to the "computed count" problem based on multiple runs of terraform apply, as you're suggesting.

@ghost
Copy link

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

Successfully merging this pull request may close these issues.

9 participants