Terraform v0.12.6
+ provider.google v2.11.0
+ provider.null v2.1.2
+ provider.random v2.1.2
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
}
Terraform plan and apply are successful and no resources are created
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.
Try to use an empty list with for_each on a resource.
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.
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.
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.
This threw me off here too here https://github.com/hashicorp/terraform/issues/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.
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.
Most helpful comment
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:
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.