diff --git a/cloud-operations/asset-inventory-feed-remediation/main.tf b/cloud-operations/asset-inventory-feed-remediation/main.tf index 1ac8d7aa8..070266819 100644 --- a/cloud-operations/asset-inventory-feed-remediation/main.tf +++ b/cloud-operations/asset-inventory-feed-remediation/main.tf @@ -63,9 +63,6 @@ module "pubsub" { project_id = module.project.project_id name = var.name subscriptions = { "${var.name}-default" = null } - iam_roles = [ - "roles/pubsub.publisher" - ] iam_members = { "roles/pubsub.publisher" = [ "serviceAccount:${module.project.service_accounts.robots.cloudasset}" diff --git a/modules/artifact-registry/README.md b/modules/artifact-registry/README.md index 480ea23ae..bf0a82cc9 100644 --- a/modules/artifact-registry/README.md +++ b/modules/artifact-registry/README.md @@ -13,7 +13,6 @@ module "docker_artifact_registry" { location = "europe-west1" format = "DOCKER" id = "myregistry" - iam_roles = ["roles/artifactregistry.admin"] iam_members = { "roles/artifactregistry.admin" = ["group:cicd@example.com"] } @@ -29,8 +28,7 @@ module "docker_artifact_registry" { | project_id | Registry project id. | string | ✓ | | | *description* | An optional description for the repository | string | | Terraform-managed registry | | *format* | Repository format. One of DOCKER or UNSPECIFIED | string | | DOCKER | -| *iam_members* | Map of member lists used to set authoritative bindings, keyed by role. | map(list(string)) | | {} | -| *iam_roles* | List of roles used to set authoritative bindings. | list(string) | | [] | +| *iam_members* | Map of member lists used to set authoritative bindings, keyed by role. | map(set(string)) | | {} | | *labels* | Labels to be attached to the registry. | map(string) | | {} | | *location* | Registry location. Use `gcloud beta artifacts locations list' to get valid values | string | | | diff --git a/modules/artifact-registry/main.tf b/modules/artifact-registry/main.tf index 81c366f42..7a7a07d22 100644 --- a/modules/artifact-registry/main.tf +++ b/modules/artifact-registry/main.tf @@ -26,10 +26,10 @@ resource "google_artifact_registry_repository" "registry" { resource "google_artifact_registry_repository_iam_binding" "bindings" { provider = google-beta - for_each = toset(var.iam_roles) + for_each = var.iam_members project = var.project_id location = google_artifact_registry_repository.registry.location repository = google_artifact_registry_repository.registry.name - role = each.value - members = lookup(var.iam_members, each.value, []) + role = each.key + members = each.value } diff --git a/modules/artifact-registry/variables.tf b/modules/artifact-registry/variables.tf index 7aa8fdcab..0726053a2 100644 --- a/modules/artifact-registry/variables.tf +++ b/modules/artifact-registry/variables.tf @@ -16,16 +16,10 @@ variable "iam_members" { description = "Map of member lists used to set authoritative bindings, keyed by role." - type = map(list(string)) + type = map(set(string)) default = {} } -variable "iam_roles" { - description = "List of roles used to set authoritative bindings." - type = list(string) - default = [] -} - variable "location" { description = "Registry location. Use `gcloud beta artifacts locations list' to get valid values" type = string diff --git a/modules/bigtable-instance/README.md b/modules/bigtable-instance/README.md index f63e1cf08..da332180b 100644 --- a/modules/bigtable-instance/README.md +++ b/modules/bigtable-instance/README.md @@ -27,7 +27,6 @@ module "big-table-instance" { } } } - iam_roles = ["viewer"] iam_members = { viewer = ["user:viewer@testdomain.com"] } @@ -45,8 +44,7 @@ module "big-table-instance" { | *cluster_id* | The ID of the Cloud Bigtable cluster. | string | | europe-west1 | | *deletion_protection* | Whether or not to allow Terraform to destroy the instance. Unless this field is set to false in Terraform state, a terraform destroy or terraform apply that would delete the instance will fail. | | | true | | *display_name* | The human-readable display name of the Bigtable instance. | | | null | -| *iam_members* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved. | map(list(string)) | | {} | -| *iam_roles* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. | list(string) | | [] | +| *iam_members* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved. | map(set(string)) | | {} | | *instance_type* | None | string | | DEVELOPMENT | | *num_nodes* | The number of nodes in your Cloud Bigtable cluster. | number | | 1 | | *storage_type* | The storage type to use. | string | | SSD | diff --git a/modules/bigtable-instance/main.tf b/modules/bigtable-instance/main.tf index 0e7129ffe..32c27bb5c 100644 --- a/modules/bigtable-instance/main.tf +++ b/modules/bigtable-instance/main.tf @@ -18,10 +18,6 @@ locals { tables = { for k, v in var.tables : k => v.table_options != null ? v.table_options : var.table_options_defaults } - - iam_roles_bindings = { - for k in var.iam_roles : k => lookup(var.iam_members, k, []) - } } resource "google_bigtable_instance" "default" { @@ -39,11 +35,11 @@ resource "google_bigtable_instance" "default" { } resource "google_bigtable_instance_iam_binding" "default" { - for_each = local.iam_roles_bindings + for_each = var.iam_members project = var.project_id instance = google_bigtable_instance.default.name - role = "roles/bigtable.${each.key}" + role = each.key members = each.value } diff --git a/modules/bigtable-instance/variables.tf b/modules/bigtable-instance/variables.tf index 7dbbaa258..0e2db64fa 100644 --- a/modules/bigtable-instance/variables.tf +++ b/modules/bigtable-instance/variables.tf @@ -14,15 +14,9 @@ * limitations under the License. */ -variable "iam_roles" { - description = "Authoritative for a given role. Updates the IAM policy to grant a role to a list of members." - type = list(string) - default = [] -} - variable "iam_members" { description = "Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved." - type = map(list(string)) + type = map(set(string)) default = {} } diff --git a/modules/cloud-function/README.md b/modules/cloud-function/README.md index ca9848f42..71e135e87 100644 --- a/modules/cloud-function/README.md +++ b/modules/cloud-function/README.md @@ -63,7 +63,6 @@ module "cf-http" { source_dir = "my-cf-source-folder" output_path = "bundle.zip" } - iam_roles = ["roles/cloudfunctions.invoker"] iam_members = { "roles/cloudfunctions.invoker" = ["allUsers"] } @@ -137,8 +136,7 @@ module "cf-http" { | *bucket_config* | Enable and configure auto-created bucket. Set fields to null to use defaults. | object({...}) | | null | | *environment_variables* | Cloud function environment variables. | map(string) | | {} | | *function_config* | Cloud function configuration. | object({...}) | | ... | -| *iam_members* | Map of member lists used to set authoritative bindings, keyed by role. Ignored for template use. | map(list(string)) | | {} | -| *iam_roles* | List of roles used to set authoritative bindings. Ignored for template use. | list(string) | | [] | +| *iam_members* | Map of member lists used to set authoritative bindings, keyed by role. Ignored for template use. | map(set(string)) | | {} | | *ingress_settings* | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL and ALLOW_INTERNAL_ONLY. | string | | null | | *labels* | Resource labels | map(string) | | {} | | *prefix* | Optional prefix used for resource names. | string | | null | diff --git a/modules/cloud-function/main.tf b/modules/cloud-function/main.tf index 224247655..3b1818a1e 100644 --- a/modules/cloud-function/main.tf +++ b/modules/cloud-function/main.tf @@ -95,12 +95,12 @@ resource "google_cloudfunctions_function" "function" { } resource "google_cloudfunctions_function_iam_binding" "default" { - for_each = toset(var.iam_roles) + for_each = var.iam_members project = var.project_id region = var.region cloud_function = google_cloudfunctions_function.function.name - role = each.value - members = try(var.iam_members[each.value], {}) + role = each.key + members = each.value } resource "google_storage_bucket" "bucket" { diff --git a/modules/cloud-function/variables.tf b/modules/cloud-function/variables.tf index eea9131fd..427e3417d 100644 --- a/modules/cloud-function/variables.tf +++ b/modules/cloud-function/variables.tf @@ -44,16 +44,10 @@ variable "environment_variables" { variable "iam_members" { description = "Map of member lists used to set authoritative bindings, keyed by role. Ignored for template use." - type = map(list(string)) + type = map(set(string)) default = {} } -variable "iam_roles" { - description = "List of roles used to set authoritative bindings. Ignored for template use." - type = list(string) - default = [] -} - variable "function_config" { description = "Cloud function configuration." type = object({ diff --git a/modules/container-registry/README.md b/modules/container-registry/README.md index 167f79b3f..ffafa387f 100644 --- a/modules/container-registry/README.md +++ b/modules/container-registry/README.md @@ -9,7 +9,6 @@ module "container_registry" { source = "../../modules/container-registry" project_id = "myproject" location = "EU" - iam_roles = ["roles/storage.admin"] iam_members = { "roles/storage.admin" = ["group:cicd@example.com"] } @@ -22,8 +21,7 @@ module "container_registry" { | name | description | type | required | default | |---|---|:---: |:---:|:---:| | project_id | Registry project id. | string | ✓ | | -| *iam_members* | Map of member lists used to set authoritative bindings, keyed by role. | map(list(string)) | | null | -| *iam_roles* | List of roles used to set authoritative bindings. | list(string) | | null | +| *iam_members* | Map of member lists used to set authoritative bindings, keyed by role. | map(set(string)) | | null | | *location* | Registry location. Can be US, EU, ASIA or empty | string | | | ## Outputs diff --git a/modules/container-registry/main.tf b/modules/container-registry/main.tf index 073e29957..7a84a281e 100644 --- a/modules/container-registry/main.tf +++ b/modules/container-registry/main.tf @@ -20,8 +20,8 @@ resource "google_container_registry" "registry" { } resource "google_storage_bucket_iam_binding" "bindings" { - for_each = toset(var.iam_roles) + for_each = var.iam_members bucket = google_container_registry.registry.id - role = each.value - members = lookup(var.iam_members, each.value, []) + role = each.key + members = each.value } diff --git a/modules/container-registry/variables.tf b/modules/container-registry/variables.tf index 15074aca7..1e5ae3f65 100644 --- a/modules/container-registry/variables.tf +++ b/modules/container-registry/variables.tf @@ -16,13 +16,7 @@ variable "iam_members" { description = "Map of member lists used to set authoritative bindings, keyed by role." - type = map(list(string)) - default = null -} - -variable "iam_roles" { - description = "List of roles used to set authoritative bindings." - type = list(string) + type = map(set(string)) default = null } diff --git a/modules/endpoints/README.md b/modules/endpoints/README.md index f57952e44..adb98de55 100644 --- a/modules/endpoints/README.md +++ b/modules/endpoints/README.md @@ -13,7 +13,6 @@ module "endpoint" { service_name = "YOUR-API.endpoints.YOUR-PROJECT-ID.cloud.goog" openapi_config = { "yaml_path" = "openapi.yaml" } grpc_config = null - iam_roles = ["servicemanagement.serviceController"] iam_members = { "servicemanagement.serviceController" = ["serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com"] } @@ -30,8 +29,7 @@ module "endpoint" { | grpc_config | The configuration for a gRPC enpoint. Either this or openapi_config must be specified. | object({...}) | ✓ | | | openapi_config | The configuration for an OpenAPI endopoint. Either this or grpc_config must be specified. | object({...}) | ✓ | | | service_name | The name of the service. Usually of the form '$apiname.endpoints.$projectid.cloud.goog'. | string | ✓ | | -| *iam_members* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved. | map(list(string)) | | {} | -| *iam_roles* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. | list(string) | | [] | +| *iam_members* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved. | map(set(string)) | | {} | | *project_id* | The project ID that the service belongs to. | string | | null | ## Outputs diff --git a/modules/endpoints/main.tf b/modules/endpoints/main.tf index 1b9cedbe0..872b7107a 100644 --- a/modules/endpoints/main.tf +++ b/modules/endpoints/main.tf @@ -14,12 +14,6 @@ * limitations under the License. */ -locals { - iam_roles_bindings = { - for k in var.iam_roles : k => lookup(var.iam_members, k, []) - } -} - resource "google_endpoints_service" "default" { project = var.project_id service_name = var.service_name @@ -29,8 +23,8 @@ resource "google_endpoints_service" "default" { } resource "google_endpoints_service_iam_binding" "default" { - for_each = local.iam_roles_bindings + for_each = var.iam_members service_name = google_endpoints_service.default.service_name - role = "roles/${each.key}" + role = each.key members = each.value } diff --git a/modules/endpoints/variables.tf b/modules/endpoints/variables.tf index 76fb8b8b6..acf23401c 100644 --- a/modules/endpoints/variables.tf +++ b/modules/endpoints/variables.tf @@ -16,27 +16,22 @@ variable "grpc_config" { description = "The configuration for a gRPC enpoint. Either this or openapi_config must be specified." - type = object({ + type = object({ yaml_path = string protoc_output_path = string }) } -variable "iam_roles" { - description = "Authoritative for a given role. Updates the IAM policy to grant a role to a list of members." - type = list(string) - default = [] -} variable "iam_members" { description = "Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved." - type = map(list(string)) + type = map(set(string)) default = {} } variable "openapi_config" { description = "The configuration for an OpenAPI endopoint. Either this or grpc_config must be specified." - type = object({ + type = object({ yaml_path = string }) } diff --git a/modules/pubsub/README.md b/modules/pubsub/README.md index 4b672760f..974fe42c4 100644 --- a/modules/pubsub/README.md +++ b/modules/pubsub/README.md @@ -12,10 +12,6 @@ module "pubsub" { source = "./modules/pubsub" project_id = "my-project" name = "my-topic" - iam_roles = [ - "roles/pubsub.viewer", - "roles/pubsub.subscriber" - ] iam_members = { "roles/pubsub.viewer" = ["group:foo@example.com"] "roles/pubsub.subscriber" = ["user:user1@example.com"] @@ -80,9 +76,6 @@ module "pubsub" { test-1 = null test-1 = null } - subscription_iam_roles = { - test-1 = ["roles/pubsub.subscriber"] - } subscription_iam_members = { test-1 = { "roles/pubsub.subscriber" = ["user:user1@ludomagno.net"] @@ -100,14 +93,12 @@ module "pubsub" { | project_id | Project used for resources. | string | ✓ | | | *dead_letter_configs* | Per-subscription dead letter policy configuration. | map(object({...})) | | {} | | *defaults* | Subscription defaults for options. | object({...}) | | ... | -| *iam_members* | IAM members for each topic role. | map(list(string)) | | {} | -| *iam_roles* | IAM roles for topic. | list(string) | | [] | +| *iam_members* | IAM members for each topic role. | map(set(string)) | | {} | | *kms_key* | KMS customer managed encryption key. | string | | null | | *labels* | Labels. | map(string) | | {} | | *push_configs* | Push subscription configurations. | map(object({...})) | | {} | | *regions* | List of regions used to set persistence policy. | list(string) | | [] | -| *subscription_iam_members* | IAM members for each subscription and role. | map(map(list(string))) | | {} | -| *subscription_iam_roles* | IAM roles for each subscription. | map(list(string)) | | {} | +| *subscription_iam_members* | IAM members for each subscription and role. | map(map(set(string))) | | {} | | *subscriptions* | Topic subscriptions. Also define push configs for push subscriptions. If options is set to null subscription defaults will be used. Labels default to topic labels if set to null. | map(object({...})) | | {} | ## Outputs diff --git a/modules/pubsub/main.tf b/modules/pubsub/main.tf index 508760704..31caa2585 100644 --- a/modules/pubsub/main.tf +++ b/modules/pubsub/main.tf @@ -15,17 +15,15 @@ */ locals { - iam_pairs = var.subscription_iam_roles == null ? [] : flatten([ - for name, roles in var.subscription_iam_roles : - [for role in roles : { name = name, role = role }] + sub_iam_members = flatten([ + for sub, roles in var.subscription_iam_members : [ + for role, members in roles : { + sub = sub + role = role + members = members + } + ] ]) - iam_keypairs = { - for pair in local.iam_pairs : - "${pair.name}-${pair.role}" => pair - } - iam_members = ( - var.subscription_iam_members == null ? {} : var.subscription_iam_members - ) oidc_config = { for k, v in var.push_configs : k => v.oidc_token } @@ -52,11 +50,11 @@ resource "google_pubsub_topic" "default" { } resource "google_pubsub_topic_iam_binding" "default" { - for_each = toset(var.iam_roles) + for_each = var.iam_members project = var.project_id topic = google_pubsub_topic.default.name - role = each.value - members = lookup(var.iam_members, each.value, []) + role = each.key + members = each.value } resource "google_pubsub_subscription" "default" { @@ -103,11 +101,12 @@ resource "google_pubsub_subscription" "default" { } resource "google_pubsub_subscription_iam_binding" "default" { - for_each = local.iam_keypairs + for_each = { + for binding in local.sub_iam_members : + "${binding.sub}.${binding.role}" => binding + } project = var.project_id - subscription = google_pubsub_subscription.default[each.value.name].name + subscription = google_pubsub_subscription.default[each.value.sub].name role = each.value.role - members = lookup( - lookup(local.iam_members, each.value.name, {}), each.value.role, [] - ) + members = each.value.members } diff --git a/modules/pubsub/variables.tf b/modules/pubsub/variables.tf index d642c7a61..e6b15083f 100644 --- a/modules/pubsub/variables.tf +++ b/modules/pubsub/variables.tf @@ -41,16 +41,10 @@ variable "defaults" { variable "iam_members" { description = "IAM members for each topic role." - type = map(list(string)) + type = map(set(string)) default = {} } -variable "iam_roles" { - description = "IAM roles for topic." - type = list(string) - default = [] -} - variable "kms_key" { description = "KMS customer managed encryption key." type = string @@ -109,12 +103,6 @@ variable "subscriptions" { variable "subscription_iam_members" { description = "IAM members for each subscription and role." - type = map(map(list(string))) - default = {} -} - -variable "subscription_iam_roles" { - description = "IAM roles for each subscription." - type = map(list(string)) + type = map(map(set(string))) default = {} } diff --git a/modules/source-repository/README.md b/modules/source-repository/README.md index c5a2eb85b..9beae2447 100644 --- a/modules/source-repository/README.md +++ b/modules/source-repository/README.md @@ -12,7 +12,6 @@ module "repo" { source e = "./modules/source-repository" project_id = "my-project" name = "my-repo" - iam_roles = ["roles/source.reader"] iam_members = { "roles/source.reader" = ["user:foo@example.com"] } @@ -26,8 +25,7 @@ module "repo" { |---|---|:---: |:---:|:---:| | name | Repository topic name. | string | ✓ | | | project_id | Project used for resources. | string | ✓ | | -| *iam_members* | IAM members for each topic role. | map(list(string)) | | {} | -| *iam_roles* | IAM roles for topic. | list(string) | | [] | +| *iam_members* | IAM members for each topic role. | map(set(string)) | | {} | ## Outputs diff --git a/modules/source-repository/main.tf b/modules/source-repository/main.tf index 810b44821..71432e16a 100644 --- a/modules/source-repository/main.tf +++ b/modules/source-repository/main.tf @@ -20,11 +20,11 @@ resource "google_sourcerepo_repository" "default" { } resource "google_sourcerepo_repository_iam_binding" "default" { - for_each = toset(var.iam_roles) + for_each = var.iam_members project = var.project_id repository = google_sourcerepo_repository.default.name - role = each.value - members = lookup(var.iam_members, each.value, []) + role = each.key + members = each.value depends_on = [ google_sourcerepo_repository.default diff --git a/modules/source-repository/variables.tf b/modules/source-repository/variables.tf index 1725d4b48..a7254370f 100644 --- a/modules/source-repository/variables.tf +++ b/modules/source-repository/variables.tf @@ -21,16 +21,10 @@ variable "project_id" { variable "iam_members" { description = "IAM members for each topic role." - type = map(list(string)) + type = map(set(string)) default = {} } -variable "iam_roles" { - description = "IAM roles for topic." - type = list(string) - default = [] -} - variable "name" { description = "Repository topic name." type = string