Summary
The IAM member resources in the terraform/modules/gcp-permission module build their for_each map keys from a dynamically computed value (the role name). Because these role values are only known at apply time, Terraform cannot determine the for_each keys during planning and fails with an "Invalid for_each argument" error.
Affected files
terraform/modules/gcp-permission/folder.tf — google_folder_iam_member.folder_level_permissions
terraform/modules/gcp-permission/project.tf — google_project_iam_member.project_level_permissions
Details
The roles originate from the module output module.pantheon_gcp_roles.necessary_gcp_roles, which is passed into the module via var.pantheon_gcp_roles (see pantheon_one_o/main.tf). This output is a computed value that is not known at plan time.
The for_each key is constructed from this dynamic value:
for_each = local.is_project_level ? { for entry in local.project_roles : "${entry.role}.${entry.projectId}" => entry } : {}
Since entry.role is unknown until apply, the resulting map keys are also unknown, producing:
Error: Invalid for_each argument
The "for_each" map includes keys derived from resource attributes that
cannot be determined until apply, and so Terraform cannot determine the
full set of keys that will identify the instances of this resource.
Expected behavior
The module should plan and apply successfully regardless of whether the role list is statically defined or computed from another module output.
Proposed fix
Use the static list index of the flattened local.*_roles list as the for_each map key instead of a key derived from the dynamic role value. The indices are known at plan time independently of the (dynamic) element values:
# project.tf
for_each = local.is_project_level ? { for idx, entry in local.project_roles : idx => entry } : {}
The same fix has already been applied to folder.tf:
# folder.tf
for_each = local.is_folder_level ? { for idx, entry in local.folder_roles : idx => entry } : {}
Summary
The IAM member resources in the
terraform/modules/gcp-permissionmodule build theirfor_eachmap keys from a dynamically computed value (the role name). Because these role values are only known at apply time, Terraform cannot determine thefor_eachkeys during planning and fails with an "Invalid for_each argument" error.Affected files
terraform/modules/gcp-permission/folder.tf—google_folder_iam_member.folder_level_permissionsterraform/modules/gcp-permission/project.tf—google_project_iam_member.project_level_permissionsDetails
The roles originate from the module output
module.pantheon_gcp_roles.necessary_gcp_roles, which is passed into the module viavar.pantheon_gcp_roles(seepantheon_one_o/main.tf). This output is a computed value that is not known at plan time.The
for_eachkey is constructed from this dynamic value:Since
entry.roleis unknown until apply, the resulting map keys are also unknown, producing:Expected behavior
The module should plan and apply successfully regardless of whether the role list is statically defined or computed from another module output.
Proposed fix
Use the static list index of the flattened
local.*_roleslist as thefor_eachmap key instead of a key derived from the dynamic role value. The indices are known at plan time independently of the (dynamic) element values:The same fix has already been applied to
folder.tf: