hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.

Home Page:https://www.terraform.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't count lists in local vars if they contain non-created resources

awilkins opened this issue · comments

This works fine

$ terraform console 
> length(list("", "1", "")
3

But if you do

locals {
  list_of_things = [
    "${a_resource.one.id}",
    "${a_resource.two.id}",
    "${a_resource.three.id}"
  ]
}

Then this will fail as it's unable to compute the count... unless the items in list_of_things already exist, when it works. This means you can extend scripts that plan and run successfully but if you then destroy the resources and start from scratch they don't work.

resource "another_resource" "thing" {
  count = "${length(local.list_of_things)}"
}

Workaround : replace count with a literal count or local or var variable with a literal value.

Hi @awilkins! Sorry this isn't working as expected.

Based on the examples you gave, I assume you're referring specifically to the "count cannot be computed" error message, which would result here because of the current limitation that a list that contains a computed value is turned into a wholly-computed list when it is the final result of an interpolation, which is a historical limitation of the interpolation language.

This is one of the weird issues that should be addressed by the improvements to the configuration language that are currently codenamed HCL2, though it'll take a few iterations before this fully works because some reorganization of Terraform Core is needed to allow it to represent these partially-computed values.

Any idea when HCL2 will be used? cause the current state of thing in HCL seems to be ... challenging. #18015 is by far not the first hiccup I had when the language couldn't do something which I thought was perfectly fine and straightforward (#953, #15896, #13022 - to name a few I remember).

The hard issue for me in this is that it removes predicatbility. You figure out something nice, elegant, clever, or just even "working" - only to realize that in fact it doesn't work, although nothing in the docs indicate that it actually shouldn't beforehand. Then you lose a lot of time sometimes just to realize that your use case just evaporated and TF isn't in fact as useful as you thought it would when you started (e.g. less automation, more manual workaround, the configuration savings you wanted can't be reached, etc. pp.).

Hi all! Sorry for the long silence here.

I'm pleased to report that this is now fixed on the master branch ready for inclusion in the forthcoming v0.12.0 release, which I just confirmed using the v0.12.0-alpha1 build.

I used the following configuration:

resource "null_resource" "a" {
}

Before applying this change, the id of this resource is not known yet as expected, but we can now take the length of a list that includes it without that the length also being unknown:

$ terraform console
> null_resource.a.id

Error: Result depends on values that cannot be determined until after "terraform apply".

> length([null_resource.a.id])
1

Thanks for reporting this issue, and for your patience while we worked to get HCL2 integrated. Since this is now fixed in master, I'm going to close this issue.

Great news this is fixed and coming soon. Does this also apply to var or just local ?

The fundamental change for v0.12 is that Terraform now uses the same representation of values in all cases, whereas before variables and outputs were implemented one way, locals a different way, and resource attributes a different way again. This unification of types and values is the root thing that has addressed most of the bugs that the v0.12 changes are addressing. (and, naturally, why v0.12 has been one of the most challenging releases to date from a development standpoint.)

...which is a long way of saying: yes, this fix applies to any list, whether it be one passed in a variable, stored in a local value, or even a temporary list result as part of evaluating a larger expression.

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.