diff --git a/modules/cloud-run-v2/README.md b/modules/cloud-run-v2/README.md index 4b0ce549e..65d62f630 100644 --- a/modules/cloud-run-v2/README.md +++ b/modules/cloud-run-v2/README.md @@ -15,7 +15,6 @@ Cloud Run Services and Jobs, with support for IAM roles and Eventarc trigger cre - [PubSub](#pubsub) - [Audit logs](#audit-logs) - [GCS bucket](#gcs-bucket) - - [Using custom service accounts for triggers](#using-custom-service-accounts-for-triggers) - [Cloud Run Invoker IAM Disable](#cloud-run-invoker-iam-disable) - [Cloud Run Service Account](#cloud-run-service-account) - [Creating Cloud Run Jobs](#creating-cloud-run-jobs) @@ -614,10 +613,13 @@ module "cloud_run" { } service_account_create = true } + service_account_email = module.iam-service-account.email + } + iam = { + "roles/run.invoker" = [module.iam-service-account.iam_email] } - deletion_protection = false } -# tftest inventory=service-eventarc-auditlogs-sa-create.yaml +# tftest fixtures=fixtures/iam-service-account.tf inventory=service-eventarc-auditlogs-external-sa.yaml e2e ``` ### GCS bucket @@ -659,93 +661,6 @@ resource "google_project_iam_member" "trigger_sa_event_receiver" { # tftest fixtures=fixtures/gcs.tf,fixtures/iam-service-account.tf inventory=service-eventarc-storage.yaml e2e ``` -### Using custom service accounts for triggers - -By default `Compute default service account` is used to trigger Cloud Run. If you want to use custom Service Accounts you can either provide your own in `eventarc_triggers.service_account_email` or set `eventarc_triggers.service_account_create` to true and service account named `tf-cr-trigger-${var.name}` will be created with `roles/run.invoker` granted on this Cloud Run service. - -Example using provided service account: - -```hcl -module "cloud_run" { - source = "./fabric/modules/cloud-run-v2" - project_id = var.project_id - region = var.region - name = "hello" - containers = { - hello = { - image = "us-docker.pkg.dev/cloudrun/container/hello" - } - } - service_config = { - eventarc_triggers = { - audit_log = { - setiampolicy = { - method = "SetIamPolicy" - service = "cloudresourcemanager.googleapis.com" - } - } - service_account_email = module.iam-service-account.email - } - } -} -# tftest fixtures=fixtures/iam-service-account.tf inventory=service-eventarc-auditlogs-external-sa.yaml e2e -``` - -Example using automatically created service account: - -```hcl -module "cloud_run" { - source = "./fabric/modules/cloud-run-v2" - project_id = var.project_id - region = var.region - name = "hello" - containers = { - hello = { - image = "us-docker.pkg.dev/cloudrun/container/hello" - } - } - service_config = { - eventarc_triggers = { - pubsub = { - topic-1 = module.pubsub.topic.name - } - service_account_create = true - } - } - deletion_protection = false -} -# tftest fixtures=fixtures/pubsub.tf inventory=service-eventarc-pubsub-sa-create.yaml e2e -``` - -Example using automatically created service account for storage triggers: - -```hcl -module "cloud_run" { - source = "./fabric/modules/cloud-run-v2" - project_id = var.project_id - region = var.region - name = "hello" - containers = { - hello = { - image = "us-docker.pkg.dev/cloudrun/container/hello" - } - } - service_config = { - eventarc_triggers = { - storage = { - bucket-upload = { - bucket = module.gcs.name - path = "/webhook" # optional: URL path for the Cloud Run service - } - } - service_account_create = true - } - } - deletion_protection = false -} -# tftest fixtures=fixtures/gcs.tf inventory=service-eventarc-storage-sa-create.yaml e2e -``` - ## Cloud Run Invoker IAM Disable To disables IAM permission check for `run.routes.invoke` for callers of this service set the `invoker_iam_disabled` variable of the module to `true` (default `false`). There should be no requirement to pass the `roles/run.invoker` to the IAM block to enable public access. This allows for the org policy `domain restricted sharing` org policy remain enabled. @@ -1041,28 +956,50 @@ module "worker" { ## Variables -| name | description | type | required | default | -|---|---|:---:|:---:|:---:| -| [name](variables.tf#L152) | Name used for Cloud Run service. | string | ✓ | | -| [project_id](variables.tf#L157) | Project id used for all resources. | string | ✓ | | -| [region](variables.tf#L162) | Region used for all resources. | string | ✓ | | -| [containers](variables.tf#L17) | Containers in name => attributes format. | map(object({…})) | | {} | -| [deletion_protection](variables.tf#L89) | Deletion protection setting for this Cloud Run service. | string | | null | -| [encryption_key](variables.tf#L95) | The full resource name of the Cloud KMS CryptoKey. | string | | null | -| [iam](variables.tf#L101) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [job_config](variables.tf#L107) | Cloud Run Job specific configuration. | object({…}) | | {} | -| [labels](variables.tf#L122) | Resource labels. | map(string) | | {} | -| [launch_stage](variables.tf#L128) | The launch stage as defined by Google Cloud Platform Launch Stages. | string | | null | -| [managed_revision](variables.tf#L145) | Whether the Terraform module should control the deployment of revisions. | bool | | true | -| [revision](variables.tf#L167) | Revision template configurations. | object({…}) | | {} | -| [service_account](variables.tf#L227) | Service account email. Unused if service account is auto-created. | string | | null | -| [service_account_create](variables.tf#L233) | Auto-create service account. | bool | | false | -| [service_config](variables.tf#L239) | Cloud Run service specific configuration options. | object({…}) | | {} | -| [tag_bindings](variables.tf#L303) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} | -| [type](variables.tf#L310) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | string | | "SERVICE" | -| [volumes](variables.tf#L320) | Named volumes in containers in name => attributes format. | map(object({…})) | | {} | -| [vpc_connector_create](variables-vpcconnector.tf#L17) | Populate this to create a Serverless VPC Access connector. | object({…}) | | null | -| [workerpool_config](variables.tf#L354) | Cloud Run Worker Pool specific configuration. | object({…}) | | {} | +| name | description | type | required | default | +|--------------------------------------------------------|---|:---:|:---:|:---:| +| [name](variables.tf#L152) | Name used for Cloud Run service. | string | ✓ | | +| [project_id](variables.tf#L157) | Project id used for all resources. | string | ✓ | | +| [region](variables.tf#L162) | Region used for all resources. | string | ✓ | | +| [containers](variables.tf#L17) | Containers in name => attributes format. | map(object({…})) | | {} | +| [deletion_protection](variables.tf#L89) | Deletion protection setting for this Cloud Run service. | string | | null | +| [encryption_key](variables.tf#L95) | The full resource name of the Cloud KMS CryptoKey. | string | | null | +| [iam](variables.tf#L101) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [job_config](variables.tf#L107) | Cloud Run Job specific configuration. | object({…}) | | {} | +| [labels](variables.tf#L122) | Resource labels. | map(string) | | {} | +| [launch_stage](variables.tf#L128) | The launch stage as defined by Google Cloud Platform Launch Stages. | string | | null | +| [managed_revision](variables.tf#L145) | Whether the Terraform module should control the deployment of revisions. | bool | | true | +| [revision](variables.tf#L167) | Revision template configurations. | object({…}) | | {} | +| [service_account](variables.tf#L227) | Service account email. Unused if service account is auto-created. | string | | null | +| [service_account_create](variables.tf#L233) | Auto-create service account. | bool | | false | +| [service_config](variables.tf#L239) | Cloud Run service specific configuration options. | object({…}) | | {} | +| [tag_bindings](variables.tf#L303) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} | +| [type](variables.tf#L310) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | string | | "SERVICE" | +| [volumes](variables.tf#L320) | Named volumes in containers in name => attributes format. | map(object({…})) | | {} | +| [name](variables.tf#L209) | Name used for Cloud Run service. | string | ✓ | | +| [project_id](variables.tf#L224) | Project id used for all resources. | string | ✓ | | +| [region](variables.tf#L229) | Region used for all resources. | string | ✓ | | +| [containers](variables.tf#L17) | Containers in name => attributes format. | map(object({…})) | | {} | +| [create_job](variables.tf#L80) | Create Cloud Run Job instead of Service. | bool | | false | +| [custom_audiences](variables.tf#L86) | Custom audiences for service. | list(string) | | null | +| [deletion_protection](variables.tf#L92) | Deletion protection setting for this Cloud Run service. | string | | null | +| [encryption_key](variables.tf#L98) | The full resource name of the Cloud KMS CryptoKey. | string | | null | +| [eventarc_triggers](variables.tf#L104) | Event arc triggers for different sources. | object({…}) | | {} | +| [iam](variables.tf#L125) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [iap_config](variables.tf#L131) | If present, turns on Identity-Aware Proxy (IAP) for the Cloud Run service. | object({…}) | | null | +| [ingress](variables.tf#L156) | Ingress settings. | string | | null | +| [invoker_iam_disabled](variables.tf#L173) | Disables IAM permission check for run.routes.invoke for callers of this service. | bool | | false | +| [labels](variables.tf#L179) | Resource labels. | map(string) | | {} | +| [launch_stage](variables.tf#L185) | The launch stage as defined by Google Cloud Platform Launch Stages. | string | | null | +| [managed_revision](variables.tf#L202) | Whether the Terraform module should control the deployment of revisions. | bool | | true | +| [prefix](variables.tf#L214) | Optional prefix used for resource names. | string | | null | +| [revision](variables.tf#L234) | Revision template configurations. | object({…}) | | {} | +| [service_account](variables.tf#L273) | Service account email. Unused if service account is auto-created. | string | | null | +| [service_account_create](variables.tf#L279) | Auto-create service account. | bool | | false | +| [tag_bindings](variables.tf#L285) | Tag bindings for this service, in key => tag value id format. | map(string) | | {} | +| [volumes](variables.tf#L292) | Named volumes in containers in name => attributes format. | map(object({…})) | | {} | +| [vpc_connector_create](variables-vpcconnector.tf#L17) | Populate this to create a Serverless VPC Access connector. | object({…}) | | null | +| [workerpool_config](variables.tf#L354) | Cloud Run Worker Pool specific configuration. | object({…}) | | {} | ## Outputs diff --git a/modules/cloud-run-v2/main.tf b/modules/cloud-run-v2/main.tf index f94927519..8f52c9f91 100644 --- a/modules/cloud-run-v2/main.tf +++ b/modules/cloud-run-v2/main.tf @@ -66,28 +66,6 @@ locals { project = local._resource[var.type].project uri = var.type == "SERVICE" ? local._resource[var.type].uri : "" } - trigger_sa_create = try( - var.service_config.eventarc_triggers.service_account_create, false - ) - trigger_sa_email = try( - google_service_account.trigger_service_account[0].email, - var.service_config.eventarc_triggers.service_account_email, - null - ) -} - -resource "google_cloud_run_v2_service_iam_member" "default" { - # if authoritative invoker role is not present and we create trigger sa - # use additive binding to grant it the role - count = ( - lookup(var.iam, "roles/run.invoker", null) == null && - local.trigger_sa_create - ) ? 1 : 0 - project = google_cloud_run_v2_service.service[0].project - location = google_cloud_run_v2_service.service[0].location - name = google_cloud_run_v2_service.service[0].name - role = "roles/run.invoker" - member = "serviceAccount:${local.trigger_sa_email}" } resource "google_service_account" "service_account" { @@ -120,7 +98,7 @@ resource "google_eventarc_trigger" "audit_log_triggers" { region = google_cloud_run_v2_service.service[0].location } } - service_account = local.trigger_sa_email + service_account = var.eventarc_triggers.service_account_email } resource "google_eventarc_trigger" "pubsub_triggers" { @@ -143,7 +121,7 @@ resource "google_eventarc_trigger" "pubsub_triggers" { region = google_cloud_run_v2_service.service[0].location } } - service_account = local.trigger_sa_email + service_account = var.eventarc_triggers.service_account_email } resource "google_eventarc_trigger" "storage_triggers" { @@ -166,22 +144,5 @@ resource "google_eventarc_trigger" "storage_triggers" { path = try(each.value.path, null) } } - service_account = local.trigger_sa_email - depends_on = [ - google_project_iam_member.trigger_sa_event_receiver - ] -} - -resource "google_service_account" "trigger_service_account" { - count = local.trigger_sa_create ? 1 : 0 - project = var.project_id - account_id = "tf-cr-trigger-${var.name}" - display_name = "Terraform trigger for Cloud Run ${var.name}." -} - -resource "google_project_iam_member" "trigger_sa_event_receiver" { - count = local.trigger_sa_create ? 1 : 0 - member = google_service_account.trigger_service_account[0].member - project = var.project_id - role = "roles/eventarc.eventReceiver" + service_account = var.eventarc_triggers.service_account_email } diff --git a/modules/cloud-run-v2/service.tf b/modules/cloud-run-v2/service.tf index 05074e687..0d0de99e4 100644 --- a/modules/cloud-run-v2/service.tf +++ b/modules/cloud-run-v2/service.tf @@ -523,14 +523,7 @@ resource "google_cloud_run_v2_service_iam_binding" "binding" { location = local.resource.location name = local.resource.name role = each.key - members = ( - each.key != "roles/run.invoker" || !local.trigger_sa_create - ? each.value - # if invoker role is present and we create trigger sa, add it as member - : concat( - each.value, ["serviceAccount:${local.trigger_sa_email}"] - ) - ) + members = each.value } resource "google_iap_web_cloud_run_service_iam_member" "member" { diff --git a/modules/cloud-run-v2/variables.tf b/modules/cloud-run-v2/variables.tf index a540a17a9..5894b2b2c 100644 --- a/modules/cloud-run-v2/variables.tf +++ b/modules/cloud-run-v2/variables.tf @@ -252,7 +252,6 @@ variable "service_config" { path = optional(string) }))) service_account_email = optional(string) - service_account_create = optional(bool, false) }), {}) gen2_execution_environment = optional(bool, false) iap_config = optional(object({ diff --git a/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-external-sa.yaml b/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-external-sa.yaml index 00ed77467..055cb620c 100644 --- a/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-external-sa.yaml +++ b/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-external-sa.yaml @@ -53,8 +53,10 @@ values: counts: google_cloud_run_v2_service: 1 + google_cloud_run_v2_service_iam_binding: 1 google_eventarc_trigger: 1 + google_service_account: 1 modules: 2 - resources: 3 + resources: 4 outputs: {} diff --git a/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-sa-create.yaml b/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-sa-create.yaml deleted file mode 100644 index f38d3f512..000000000 --- a/tests/modules/cloud_run_v2/examples/service-eventarc-auditlogs-sa-create.yaml +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -values: - module.cloud_run.google_cloud_run_v2_service_iam_member.default[0]: - condition: [] - location: europe-west8 - name: hello - project: project-id - role: roles/run.invoker - module.cloud_run.google_cloud_run_v2_service.service[0]: - location: europe-west8 - name: hello - project: project-id - template: - - containers: - - args: null - command: null - depends_on: null - env: [] - image: us-docker.pkg.dev/cloudrun/container/hello - name: hello - volume_mounts: [] - working_dir: null - execution_environment: EXECUTION_ENVIRONMENT_GEN1 - volumes: [] - vpc_access: [] - timeouts: null - module.cloud_run.google_eventarc_trigger.audit_log_triggers["setiampolicy"]: - destination: - - cloud_run_service: - - path: null - region: europe-west8 - service: hello - location: europe-west8 - matching_criteria: - - attribute: methodName - operator: '' - value: SetIamPolicy - - attribute: serviceName - operator: '' - value: cloudresourcemanager.googleapis.com - - attribute: type - operator: '' - value: google.cloud.audit.log.v1.written - name: audit-log-setiampolicy - project: project-id - module.cloud_run.google_service_account.trigger_service_account[0]: - account_id: tf-cr-trigger-hello - description: null - disabled: false - display_name: Terraform trigger for Cloud Run hello. - project: project-id - -counts: - google_cloud_run_v2_service_iam_member: 1 - google_cloud_run_v2_service: 1 - google_eventarc_trigger: 1 - google_service_account: 1 - modules: 1 - resources: 5 - -outputs: {} diff --git a/tests/modules/cloud_run_v2/examples/service-eventarc-pubsub-sa-create.yaml b/tests/modules/cloud_run_v2/examples/service-eventarc-pubsub-sa-create.yaml deleted file mode 100644 index cf7cc7270..000000000 --- a/tests/modules/cloud_run_v2/examples/service-eventarc-pubsub-sa-create.yaml +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -values: - module.cloud_run.google_cloud_run_v2_service_iam_member.default[0]: - condition: [] - location: europe-west8 - name: hello - project: project-id - role: roles/run.invoker - module.cloud_run.google_cloud_run_v2_service.service[0]: - location: europe-west8 - name: hello - project: project-id - template: - - containers: - - args: null - command: null - depends_on: null - env: [] - image: us-docker.pkg.dev/cloudrun/container/hello - name: hello - volume_mounts: [] - working_dir: null - execution_environment: EXECUTION_ENVIRONMENT_GEN1 - volumes: [] - vpc_access: [] - module.cloud_run.google_eventarc_trigger.pubsub_triggers["topic-1"]: - destination: - - cloud_run_service: - - path: null - region: europe-west8 - service: hello - location: europe-west8 - matching_criteria: - - attribute: type - operator: '' - value: google.cloud.pubsub.topic.v1.messagePublished - name: pubsub-topic-1 - project: project-id - transport: - - pubsub: - - topic: topic - module.cloud_run.google_service_account.trigger_service_account[0]: - account_id: tf-cr-trigger-hello - description: null - disabled: false - display_name: Terraform trigger for Cloud Run hello. - project: project-id - timeouts: null - -counts: - google_cloud_run_v2_service_iam_member: 1 - google_cloud_run_v2_service: 1 - google_eventarc_trigger: 1 - google_service_account: 1 - modules: 2 - resources: 7 - -outputs: {} diff --git a/tests/modules/cloud_run_v2/examples/service-eventarc-storage-sa-create.yaml b/tests/modules/cloud_run_v2/examples/service-eventarc-storage-sa-create.yaml deleted file mode 100644 index bf19947c4..000000000 --- a/tests/modules/cloud_run_v2/examples/service-eventarc-storage-sa-create.yaml +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -values: - module.cloud_run.google_cloud_run_v2_service.service[0]: - location: europe-west8 - name: hello - project: project-id - template: - - containers: - - args: null - command: null - depends_on: null - env: [] - image: us-docker.pkg.dev/cloudrun/container/hello - name: hello - volume_mounts: [] - working_dir: null - execution_environment: EXECUTION_ENVIRONMENT_GEN1 - volumes: [] - vpc_access: [] - - module.cloud_run.google_eventarc_trigger.storage_triggers["bucket-upload"]: - destination: - - cloud_run_service: - - path: /webhook - region: europe-west8 - service: hello - location: europe-west8 - matching_criteria: - - attribute: bucket - operator: '' - value: test-my-bucket - - attribute: type - operator: '' - value: google.cloud.storage.object.v1.finalized - name: storage-bucket-upload - project: project-id - - module.cloud_run.google_service_account.trigger_service_account[0]: - account_id: tf-cr-trigger-hello - description: null - disabled: false - display_name: Terraform trigger for Cloud Run hello. - project: project-id - timeouts: null - - module.cloud_run.google_cloud_run_v2_service_iam_member.default[0]: - condition: [] - member: serviceAccount:tf-cr-trigger-hello@project-id.iam.gserviceaccount.com - project: project-id - role: roles/run.invoker - -counts: - google_cloud_run_v2_service: 1 - google_cloud_run_v2_service_iam_member: 1 - google_eventarc_trigger: 1 - google_service_account: 1 - modules: 2 - resources: 7 - -outputs: {}