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

Resource for_each not working with empty list #22281

Closed
adarobin opened this issue Aug 1, 2019 · 4 comments · Fixed by #22756
Closed

Resource for_each not working with empty list #22281

adarobin opened this issue Aug 1, 2019 · 4 comments · Fixed by #22756
Assignees
Labels
bug config v0.12 Issues (primarily bugs) reported against v0.12 releases

Comments

@adarobin
Copy link

adarobin commented Aug 1, 2019

Terraform Version

Terraform v0.12.6
+ provider.google v2.11.0
+ provider.null v2.1.2
+ provider.random v2.1.2

Terraform Configuration Files

variable "datalab_user_list" {
    type = list(string)
    default = []

}
resource "google_service_account" "datalab_service_account" {
    for_each = toset(var.datalab_user_list)
    account_id = "datalab-${split("@", each.key)[0]}"
    project = google_project.hipaa_project.project_id
}

Debug Output

Crash Output

Expected Behavior

Terraform plan and apply are successful and no resources are created

Actual Behavior

Error: Invalid for_each set argument

  on .terraform/modules/hipaa_worker_project1/datalab.tf line 23, in resource "google_service_account" "datalab_service_account":
  23:     for_each = toset(var.datalab_user_list)

The given "for_each" argument value is unsuitable: "for_each" supports maps
and sets of strings, but you have provided a set containing type dynamic.

Steps to Reproduce

Try to use an empty list with for_each on a resource.

Additional Context

As a workaround, this seems to work fine:

variable "datalab_user_list" {
    type = "map"
    default = {}

}
resource "google_service_account" "datalab_service_account" {
    for_each = var.datalab_user_list
    account_id = "datalab-${split("@", each.key)[0]}"
    project = google_project.hipaa_project.project_id
}

However, I don't really need a map and it makes what I pass in to the module a bit more confusing to read.

References

@adarobin
Copy link
Author

adarobin commented Aug 1, 2019

I also tried:

variable "datalab_user_list" {
    type = list(string)
    default = [ "" ]
}
resource "google_service_account" "datalab_service_account" {
    for_each = toset(compact(var.datalab_user_list))
    account_id = "datalab-${split("@", each.key)[0]}"
    project = google_project.hipaa_project.project_id
}

But that still throws a similar error:

Error: Invalid for_each set argument

  on .terraform/modules/hipaa_worker_project1/datalab.tf line 24, in resource "google_service_account" "datalab_service_account":
  24:     for_each = toset(compact(var.datalab_user_list))

The given "for_each" argument value is unsuitable: "for_each" supports maps
and sets of strings, but you have provided a set containing type dynamic.

@apparentlymart
Copy link
Contributor

Ahh, thanks for reporting this!

Indeed, this is a quirk caused by the fact that in toset([]) there are no elements to hint the function as to what the set element type should be, and so "dynamic" here really means "unknown".

For now I think the most reliable workaround would be to manually convert to a map instead of a set, which shouldn't run into the same problem because map keys are always strings:

  for_each = { for v in var.datalab_user_list : v => v }

A conversion like the above is essentially what Terraform itself does when handling a set of strings, but it checks the set element type first to produce that "Invalid for_each set element" error.

@pselle pselle added bug and removed bug labels Aug 1, 2019
@hashibot hashibot added config v0.12 Issues (primarily bugs) reported against v0.12 releases labels Aug 28, 2019
@supergibbs
Copy link
Contributor

supergibbs commented Aug 28, 2019

This threw me off here too here #22622

I use a resource with count and then for_each those on another resource. If count is 0 it fails.

I think the fix could be for_each checks the length first and aborts when 0. If there are items, then check that they are strings.

@ghost
Copy link

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

Successfully merging a pull request may close this issue.

5 participants