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

Terraform 0.13.0 "count" value depends on resource attributes that cannot be determined while using length(list) #25815

Closed
ghost opened this issue Aug 12, 2020 · 19 comments
Labels
bug new new issue not yet triaged v0.13 Issues (primarily bugs) reported against v0.13 releases waiting for reproduction unable to reproduce issue without further information

Comments

@ghost
Copy link

ghost commented Aug 12, 2020

Hi there,

with Terraform 0.13.0, terraform plan and terraform apply failed when using count = length(of_list) on a resource. For example:

A module "compute" returns a list of network interface ids:

output "network_interface_ids" {
  description = "The ids of the network interfaces of the vms"
  value       = azurerm_network_interface.main.*.id
}

In the root module, i using this list to create associations with a azure application security group:

resource "azurerm_network_interface_application_security_group_association" "vms_to_asg" {
  count                         = length(module.compute_vm.network_interface_ids)
  network_interface_id          = module.compute_vm.network_interface_ids[count.index]
  application_security_group_id = azurerm_application_security_group.asg.id
}

Terraform fails with the message:

Error: Invalid count argument

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

I have this error on multiple resources, also when i pass a list as module parameter and using the length of this with count in a module resource. Same error.

@ghost ghost added bug new new issue not yet triaged labels Aug 12, 2020
@danieldreier
Copy link
Contributor

Hello @paleeak!

We use GitHub issues for tracking bugs and enhancements, rather than for questions. While we can sometimes help with certain simple problems here, it's better to use the community forum where there are more people ready to help. The GitHub issues here are monitored only by our few core maintainers.

In this case, I think that what you're running into here is that terraform functions (like length) run at the very beginning of parsing, before we know how the results of the plan. This is an expected, although counter-intuitive behavior. I've been tracking examples of this non-obviousness at #25162.

In your particular case, I think what you're looking to do is to create a resource for the compute VMs. You should be able to do this using the new module for_each functionality, rather than count, because that won't require invoking a function.

Based on the information you've provided, it looks like this doesn't represent a specific bug or feature request, even though I understand that Terraform isn't doing what you expect it to, and so I'm going to close it. If the answer I've given here doesn't quite work, or you want to talk it through more, please do feel free to ask your question in the community forum.

@danieldreier danieldreier added question v0.13 Issues (primarily bugs) reported against v0.13 releases and removed bug new new issue not yet triaged labels Aug 12, 2020
@ghost
Copy link
Author

ghost commented Aug 12, 2020

@danieldreier I understand this place is for bugs. Iam using this code since Terraform 0.12.21 and it always works very well. So from my point, its a bug.

I dont see how for_each helps me out here. My "compute_vm" module returns a list of network_interface_ids and i just using this list to create assoications with count inside the root module.

I can try to use foreach instead of count in the azurerm_network_interface_application_security_group_association resource, but why terraform 0.13.0 works now different then terraform 0.12.x. I dont see a relevant change in the changelog on this.

@danieldreier danieldreier reopened this Aug 12, 2020
@danieldreier danieldreier added bug new new issue not yet triaged and removed question labels Aug 12, 2020
@danieldreier
Copy link
Contributor

Thanks! I didn't understand. I've put it back in the queue for triage, because it seems like my understanding was wrong.

@ghost
Copy link
Author

ghost commented Aug 13, 2020

@danieldreier

no problem. Iam sure my english is quite not the best. I will refactor by codebase, then i dont have to invoke the functions. Maybe its the way to go. But its still strange.

@JanKoppe
Copy link

I can confirm this bug. It's even happening while not changing anything. It's completely non-deterministic behaviour in our case. If I go ahead and target just the depending resource, sometimes it works after one targeted run, sometimes only after a few, sometimes never.

This is really bad and breaking some critical code for us.

@ghost
Copy link

ghost commented Aug 20, 2020

I have the same issue @danieldreier @jbardin can you reopen this issue ticket?

@danieldreier
Copy link
Contributor

Sure! The original reporter closed it, not someone on the core team, so I'll re-open and let it run through the process. If any of the folks asking want to help, what we'd really need is a clear reproduction case that is easy for an engineer here to copy and paste without inventing any details. Ideally, this would use the null resource provider rather than a real provider in order to minimize external dependencies.

@danieldreier danieldreier reopened this Aug 20, 2020
@jbardin jbardin added the waiting for reproduction unable to reproduce issue without further information label Aug 20, 2020
@remche
Copy link

remche commented Aug 25, 2020

Same here, using a null_ressource but not so minimal :
https://travis-ci.com/github/remche/terraform-openstack-rke

Note that switching to for_each throws an error, too

Error: Invalid for_each argument

  on modules/rke/main.tf line 2, in resource "null_resource" "wait_for_master_ssh":
   2:   for_each = var.master_nodes

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.

Seems linked too #25851

@remche
Copy link

remche commented Aug 25, 2020

I wrote a minimal case using only null_resource :
https://github.com/remche/tf0.13-count-foreach

Terraform 0.12.x -> OK
Terraform 0.13.0 -> KO

@JanKoppe
Copy link

Very interesting. remches testcase is reproducable for me with 0.13.0. If I use 0.13.1, the test case works fine again, but the issue that I'm seeing in our codebase still persists.

Wasn't able yet to build a minimal testcase that reproduces my issue.

@remche
Copy link

remche commented Aug 28, 2020

0.13.1 fixes the test case. In our real case, first apply operation is successful but not the second 😲

Anyway, for_each way is still broken : remche/tf0.13-count-foreach@caf950e

@jbardin
Copy link
Member

jbardin commented Sep 2, 2020

Thanks for the example, but the error from your for_each example is correct. You're attempting to use the attributes from the module/one nodes as the input to the for_each expression, which are unknown until apply.

@remche
Copy link

remche commented Sep 2, 2020

oops, you're right ;)
I switched everything to for_each in our real case and everything run smoothly now. At least this count bug makes me switch to better practices 😁

@kingsleyadam
Copy link

kingsleyadam commented Sep 3, 2020

@remche , do you have an example of how you fixed this?

I have a very similar situation as you. I'm not quite sure how to work around it. To me this is a bug. Pre 0.13.x this worked without issues for quite some time.

variable "load_balancers" {
  description = "Which load balancers to attach the servers to"
  type        = list(string)
}

data "azurerm_lb" "load_balancers" {
  for_each = {
    for index, value in var.load_balancers : index => value
  }
  name                = "${var.lb_prefix}-${var.realm}-${each.value}"
  resource_group_name = var.resource_group.name
}
data "azurerm_lb_backend_address_pool" "lb_backend_address_pools" {
  for_each = {
    for index, value in data.azurerm_lb.load_balancers : index => value
  }
  name            = "BackEndAddressPool"
  loadbalancer_id = each.value.id
}
Error: Invalid for_each argument

  on modules/virtual_machines/data.tf line 30, in data "azurerm_lb_backend_address_pool" "lb_backend_address_pools":
  30:   for_each = {
  31:     for index, value in data.azurerm_lb.load_balancers : index => value
  32:   }

The "for_each" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the for_each depends on.

@remche
Copy link

remche commented Sep 3, 2020

@kingsleyadam the second for_each loop depends on a apply-time computed value. may be you could use a local variable to build a map ?

In my case I changed the output of a module to give the failing for_each a map where index can be computed before apply.
See remche/terraform-openstack-rke@bff90c05

@kingsleyadam
Copy link

kingsleyadam commented Sep 3, 2020

Thanks @remche. I have tried using a local variable, but it produces the same result. I was able to work around this by using the same variable var.load_balancers in my second for each.

data "azurerm_lb_backend_address_pool" "lb_backend_address_pools" {
  for_each = {
    for index, value in var.load_balancers : index => value
  }
  name            = "BackEndAddressPool"
  loadbalancer_id = data.azurerm_lb.load_balancers[each.index].id
}

But then I received the same eror further down the line when I try to assign the backend pool to a list of VM's. The list of VM's is detirmined by a var.vm_count variable.

Also, sometimes I can get the entire plan to work when I target a non-related resource. And re-run the plan.

@kingsleyadam
Copy link

I was able to resolve my issues so I'm posting in case someone else comes across this. The error is very misleading, I was under the impression that terraform couldn't come up with the list of items to be created based on my for_each.

...Terraform cannot predict how many instances will be created....

The real issue was that I was using an unknown value for they key of the for each. I was using the id of the resource that was to be created, which it didn't know during apply.

The fix was to use my own configured values for the key, now all my issues are resolved.

This did work in 0.12.x. Hope this helps someone.

@jbardin
Copy link
Member

jbardin commented Sep 22, 2020

There hasn't been any additional reproductions of the bug, and things seem to be working as intended here, so we're going to re-close the issue.

Thanks!

@jbardin jbardin closed this as completed Sep 22, 2020
@github-actions
Copy link
Contributor

github-actions bot commented Jun 2, 2021

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug new new issue not yet triaged v0.13 Issues (primarily bugs) reported against v0.13 releases waiting for reproduction unable to reproduce issue without further information
Projects
None yet
Development

No branches or pull requests

5 participants