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

for_each causes terraform crash when creating null_resource #22580

Closed
muroj opened this issue Aug 24, 2019 · 6 comments · Fixed by #22597
Closed

for_each causes terraform crash when creating null_resource #22580

muroj opened this issue Aug 24, 2019 · 6 comments · Fixed by #22597
Assignees
Labels
bug crash v0.12 Issues (primarily bugs) reported against v0.12 releases

Comments

@muroj
Copy link

muroj commented Aug 24, 2019

Terraform Version

Terraform v0.12.7
+ provider.null v2.1.2

Terraform Configuration Files

variable "subnet_id" {
    description = "IP Subnet specified in CIDR notation (e.g. 10.20.102.0/24) "
}

locals {
  guest_ips = [for i in range(1,255) : cidrhost(var.subnet_id, i)]
}

resource "null_resource" "guest_ips" {
    #for_each = toset(
    #    [for i in range(1,255) : cidrhost("var.subnet_id", i)]
    #)

    for_each = toset(local.guest_ips)

    triggers = {
      all_guest_ips = each.value
    }
}

Calling module:

module "subnet_1" {
    source = "../../../../soltest-terraform-modules/modules/network/ip_range"
    subnet_id = "10.20.102.0/24"
}

Crash Output

https://gist.github.com/muroj/35b5d7ca81cdf96fe81f37e4773f4013

Expected Behavior

A null resource for each IP should have been created.

Actual Behavior

terraform crashes

Steps to Reproduce

  1. terraform init
  2. terraform plan/apply

References

Similar to #22560

@muroj
Copy link
Author

muroj commented Aug 24, 2019

Turns out I can accomplish the same (dynamic resource creation) using count instead of for_each.

For example:

main.tf

 
variable "subnet_id" {
    description = "IP Subnet specified in CIDR notation (e.g. 10.20.102.0/24) "
}
variable "host_range" {
    description = "A list specifying the available IPs"
    type = "list"
}

locals {
  guest_ips = [for i in var.host_range : cidrhost(var.subnet_id, i)]
}

resource "null_resource" "guest_ips" {

    triggers = {
      all_guest_ips = element(local.guest_ips, count.index)
    }

    count = length(local.guest_ips)
}

Here is the calling module:

module "subnet_1" {
    source = "../../../../soltest-terraform-modules/modules/libvirt/network/ip_range"
    subnet_id = "10.20.102.0/24"
    host_range = flatten([range(1,5), range(11,15)])
}

I usually do not own an entire subnet, and must share it amongst other teams (not ideal, of course). This approach allows me to specify exactly which hosts are available in a given subnet.

@jcmaasb
Copy link

jcmaasb commented Aug 26, 2019

Hi @muroj

In your case, i think it´s acomplise with this code:

variable "subnet_id" {
  description = "IP Subnet specified in CIDR notation (e.g. 10.20.102.0/24) "
  default     = "10.20.102.0/24"
}

locals {
  guest_ips = { for i in range(1, 255) : i => cidrhost(var.subnet_id, i) }
}

resource "null_resource" "guest_ips" {
  for_each = local.guest_ips

  triggers = {
    all_guest_ips = each.value
  }
}

I have some issues with for_each in resources, and i dont understant how its works.
I'm waiting for the response from the Terraform Team to know how to use lists and maps with "for_each" correctly.

@muroj
Copy link
Author

muroj commented Aug 26, 2019

Thanks @jcmaasb, your code snippet works. However, I am not clear on benefits of this approach. Why would I use for_each vs count in this case?

@pselle
Copy link
Contributor

pselle commented Aug 26, 2019

Hi @jcmaasb, I wrote a little more about what for_each is expecting and why over here: #22560 (comment) (the similar, but ultimately different issue). Notably, don't use lists with for_each, which supports maps or sets of strings (explanation in link).

For this issue (thanks @muroj for opening!) it appears it has to do with unknown values. We should not panic here, and will fix that. The rule for using expressions with count (values must be known) should apply to for_each as well, but I'll do more investigation to confirm.

Edit for further clarification: The value is unknown at one point during the plan, but becomes known. Bug found and will fix, it looked like your code should work :)

@pselle pselle added bug crash v0.12 Issues (primarily bugs) reported against v0.12 releases labels Aug 26, 2019
@pselle pselle self-assigned this Aug 26, 2019
@jcmaasb
Copy link

jcmaasb commented Aug 27, 2019

Hi @pselle
Thanks for your quick reply!!

@ghost
Copy link

ghost commented Oct 4, 2019

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 Oct 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug crash v0.12 Issues (primarily bugs) reported against v0.12 releases
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants