Skip to content

Conversation

@thatcoleyouknow
Copy link

As an engineer that works for an organization that adds new subnets on a regular basis, we find ourselves constantly having to review very lengthy Terraform plans that are full of google_compute_subnetwork_iam_member recreations. This is partly due to Terraform lists being unordered but this can now be solved for by replacing the count argument with for_each in each of those resources. This would be a one-time breaking change, but it would also make it the last time consumers have to deal subnet IAM grants getting recreated due to changes in the list of subnets passed to this module.

If you all have any questions, concerns, or suggestions, I'd be happy to talk through those. I am also an enterprise customer so I can open a feature request with our TAM to try and help prioritize this, if that would help you all.

Thank you!

…new subnet is added or removed in the host project
@thatcoleyouknow thatcoleyouknow marked this pull request as ready for review October 11, 2025 17:57
@thatcoleyouknow thatcoleyouknow requested a review from a team as a code owner October 11, 2025 17:57
@thatcoleyouknow thatcoleyouknow changed the title fix: Swap count for for_each on subnet IAM resources fix!: Swap count for for_each on subnet IAM resources Oct 11, 2025
@thatcoleyouknow thatcoleyouknow marked this pull request as draft October 11, 2025 18:04
@thatcoleyouknow thatcoleyouknow changed the title fix!: Swap count for for_each on subnet IAM resources feat!: Swap count for for_each on subnet IAM resources Oct 11, 2025
@thatcoleyouknow thatcoleyouknow marked this pull request as ready for review October 12, 2025 15:03
@thatcoleyouknow
Copy link
Author

FWIW this has been tested internally. If any issues arise once someone kicks off the checks, feel free to @ me.

@thatcoleyouknow thatcoleyouknow marked this pull request as draft October 12, 2025 23:43
@thatcoleyouknow thatcoleyouknow marked this pull request as ready for review October 12, 2025 23:51
@thatcoleyouknow
Copy link
Author

Could someone tell me what failed in the terraform-google-project-factory-int-trigger check? I don't have permissions to view that.

@thatcoleyouknow
Copy link
Author

@imrannayer - Forgive the ping but I see you are an active maintainer. Is there a preferable way to get the gcbrun command ran on this PR so I can try and work through any issues preventing this from being reviewed for merge?

@bharathkkb
Copy link
Member

/gcbrun

@thatcoleyouknow
Copy link
Author

Could someone tell me what failed in the terraform-google-project-factory-int-trigger check? I don't have permissions to view that.

Now that this job actually ran, could I get someone to share why this failed?

@bharathkkb
Copy link
Member

Hi @thatcoleyouknow , it failed when trying to apply the example dynamic-shared-vpc-local. I suspect switching to for_each is causing some values to be unknown during plan. Could you try testing that example locally?

STDERR: Error: Invalid for_each argument

  on ../../../modules/core_project_factory/main.tf line 215, in resource "google_compute_subnetwork_iam_member" "service_account_role_to_vpc_subnets":
 215:   for_each = (var.grant_network_role && var.enable_shared_vpc_service_project && length(var.shared_vpc_subnets) > 0 && var.create_project_sa) ? toset(var.shared_vpc_subnets) : toset([])
    ├────────────────
    │ var.create_project_sa is true
    │ var.enable_shared_vpc_service_project is true
    │ var.grant_network_role is true
    │ var.shared_vpc_subnets is list of string with 2 elements

The "for_each" set includes values 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.

When working with unknown values in for_each, it's better to use a map value
where the keys are defined statically in your configuration and where only
the values contain apply-time results.

Alternatively, you could use the -target planning option to first apply only
the resources that the for_each value depends on, and then apply a second
time to fully converge.

Error: Invalid for_each argument

  on ../../../modules/core_project_factory/main.tf line 265, in resource "google_compute_subnetwork_iam_member" "apis_service_account_role_to_vpc_subnets":
 265:   for_each = (var.grant_network_role && var.enable_shared_vpc_service_project && length(var.shared_vpc_subnets) > 0) ? toset(var.shared_vpc_subnets) : toset([])
    ├────────────────
    │ var.enable_shared_vpc_service_project is true
    │ var.grant_network_role is true
    │ var.shared_vpc_subnets is list of string with 2 elements

The "for_each" set includes values 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.

When working with unknown values in for_each, it's better to use a map value
where the keys are defined statically in your configuration and where only
the values contain apply-time results.

Alternatively, you could use the -target planning option to first apply only
the resources that the for_each value depends on, and then apply a second
time to fully converge.

Error: Invalid for_each argument

  on ../../../modules/shared_vpc_access/main.tf line 98, in resource "google_compute_subnetwork_iam_member" "service_shared_vpc_subnet_users":
  98:   for_each = var.grant_network_role ? toset(local.subnetwork_api) : toset([])
    ├────────────────
    │ local.subnetwork_api is list of string with 6 elements
    │ var.grant_network_role is true

The "for_each" set includes values 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.

When working with unknown values in for_each, it's better to use a map value
where the keys are defined statically in your configuration and where only
the values contain apply-time results.

Alternatively, you could use the -target planning option to first apply only
the resources that the for_each value depends on, and then apply a second
time to fully converge.

Error: Invalid for_each argument

  on ../../../modules/shared_vpc_access/main.tf line 124, in resource "google_compute_subnetwork_iam_member" "cloudservices_shared_vpc_subnet_users":
 124:   for_each = local.gke_shared_vpc_enabled && var.enable_shared_vpc_service_project && var.grant_network_role ? toset(local.subnetwork_api) : toset([])
    ├────────────────
    │ local.gke_shared_vpc_enabled is true
    │ local.subnetwork_api is list of string with 6 elements
    │ var.enable_shared_vpc_service_project is true
    │ var.grant_network_role is true

The "for_each" set includes values 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.

When working with unknown values in for_each, it's better to use a map value
where the keys are defined statically in your configuration and where only
the values contain apply-time results.

Alternatively, you could use the -target planning option to first apply only
the resources that the for_each value depends on, and then apply a second
time to fully converge.
---- End output of terraform apply -auto-approve -lock=true -lock-timeout=0s -input=false -no-color -parallelism=10 -refresh=true 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants