Add trigger SA for Cloud Run

This commit is contained in:
Wiktor Niesiobędzki
2023-05-30 14:49:14 +00:00
committed by Wiktor Niesiobędzki
parent 91daad5570
commit 3ac6ceac1e
5 changed files with 159 additions and 18 deletions

View File

@@ -218,6 +218,57 @@ module "cloud_run" {
# tftest modules=1 resources=2 inventory=audit-logs.yaml
```
#### 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 Account 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"
project_id = "my-project"
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
audit_log = {
setiampolicy = {
method = "SetIamPolicy"
service = "cloudresourcemanager.googleapis.com"
}
}
service_account_email = "cloud-run-trigger@my-project.iam.gserviceaccount.com"
}
}
# tftest modules=1 resources=2 inventory=trigger-service-account-external.yaml
```
Example using automatically created service account:
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run"
project_id = "my-project"
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
pubsub = {
topic-1 = "topic1"
topic-2 = "topic2"
}
service_account_create = true
}
}
# tftest modules=1 resources=5 inventory=trigger-service-account.yaml
```
### Service account
To use a custom service account managed by the module, set `service_account_create` to `true` and leave `service_account` set to `null` value (default).
@@ -259,24 +310,24 @@ module "cloud_run" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L121) | Name used for cloud run service. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L136) | Project id used for all resources. | <code>string</code> | ✓ | |
| [name](variables.tf#L123) | Name used for cloud run service. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L138) | Project id used for all resources. | <code>string</code> | ✓ | |
| [container_concurrency](variables.tf#L18) | Maximum allowed in-flight (concurrent) requests per container of the revision. | <code>string</code> | | <code>null</code> |
| [containers](variables.tf#L24) | Containers in arbitrary key => attributes format. | <code title="map&#40;object&#40;&#123;&#10; image &#61; string&#10; args &#61; optional&#40;list&#40;string&#41;&#41;&#10; command &#61; optional&#40;list&#40;string&#41;&#41;&#10; env &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; env_from_key &#61; optional&#40;map&#40;object&#40;&#123;&#10; key &#61; string&#10; name &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; liveness_probe &#61; optional&#40;object&#40;&#123;&#10; action &#61; object&#40;&#123;&#10; grcp &#61; optional&#40;object&#40;&#123;&#10; port &#61; optional&#40;number&#41;&#10; service &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; http_get &#61; optional&#40;object&#40;&#123;&#10; http_headers &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; path &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; failure_threshold &#61; optional&#40;number&#41;&#10; initial_delay_seconds &#61; optional&#40;number&#41;&#10; period_seconds &#61; optional&#40;number&#41;&#10; timeout_seconds &#61; optional&#40;number&#41;&#10; &#125;&#41;&#41;&#10; ports &#61; optional&#40;map&#40;object&#40;&#123;&#10; container_port &#61; optional&#40;number&#41;&#10; name &#61; optional&#40;string&#41;&#10; protocol &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; resources &#61; optional&#40;object&#40;&#123;&#10; limits &#61; optional&#40;object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#41;&#10; requests &#61; optional&#40;object&#40;&#123;&#10; cpu &#61; string&#10; memory &#61; string&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#41;&#10; startup_probe &#61; optional&#40;object&#40;&#123;&#10; action &#61; object&#40;&#123;&#10; grcp &#61; optional&#40;object&#40;&#123;&#10; port &#61; optional&#40;number&#41;&#10; service &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; http_get &#61; optional&#40;object&#40;&#123;&#10; http_headers &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; path &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10; tcp_socket &#61; optional&#40;object&#40;&#123;&#10; port &#61; optional&#40;number&#41;&#10; &#125;&#41;&#41;&#10; &#125;&#41;&#10; failure_threshold &#61; optional&#40;number&#41;&#10; initial_delay_seconds &#61; optional&#40;number&#41;&#10; period_seconds &#61; optional&#40;number&#41;&#10; timeout_seconds &#61; optional&#40;number&#41;&#10; &#125;&#41;&#41;&#10; volume_mounts &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [eventarc_triggers](variables.tf#L91) | Event arc triggers for different sources. | <code title="object&#40;&#123;&#10; audit_log &#61; optional&#40;map&#40;object&#40;&#123;&#10; method &#61; string&#10; service &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; pubsub &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L103) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_settings](variables.tf#L109) | Ingress settings. | <code>string</code> | | <code>null</code> |
| [labels](variables.tf#L115) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [prefix](variables.tf#L126) | Optional prefix used for resource names. | <code>string</code> | | <code>null</code> |
| [region](variables.tf#L141) | Region used for all resources. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [revision_annotations](variables.tf#L147) | Configure revision template annotations. | <code title="object&#40;&#123;&#10; autoscaling &#61; optional&#40;object&#40;&#123;&#10; max_scale &#61; number&#10; min_scale &#61; number&#10; &#125;&#41;&#41;&#10; cloudsql_instances &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; vpcaccess_connector &#61; optional&#40;string&#41;&#10; vpcaccess_egress &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [revision_name](variables.tf#L162) | Revision name. | <code>string</code> | | <code>null</code> |
| [service_account](variables.tf#L168) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
| [service_account_create](variables.tf#L174) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
| [timeout_seconds](variables.tf#L180) | Maximum duration the instance is allowed for responding to a request. | <code>number</code> | | <code>null</code> |
| [traffic](variables.tf#L186) | Traffic steering configuration. If revision name is null the latest revision will be used. | <code title="map&#40;object&#40;&#123;&#10; percent &#61; number&#10; latest &#61; optional&#40;bool&#41;&#10; tag &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [volumes](variables.tf#L197) | Named volumes in containers in name => attributes format. | <code title="map&#40;object&#40;&#123;&#10; secret_name &#61; string&#10; default_mode &#61; optional&#40;string&#41;&#10; items &#61; optional&#40;map&#40;object&#40;&#123;&#10; path &#61; string&#10; mode &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc_connector_create](variables.tf#L211) | Populate this to create a VPC connector. You can then refer to it in the template annotations. | <code title="object&#40;&#123;&#10; ip_cidr_range &#61; optional&#40;string&#41;&#10; vpc_self_link &#61; optional&#40;string&#41;&#10; machine_type &#61; optional&#40;string&#41;&#10; name &#61; optional&#40;string&#41;&#10; instances &#61; optional&#40;object&#40;&#123;&#10; max &#61; optional&#40;number&#41;&#10; min &#61; optional&#40;number&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; throughput &#61; optional&#40;object&#40;&#123;&#10; max &#61; optional&#40;number&#41;&#10; min &#61; optional&#40;number&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; subnet &#61; optional&#40;object&#40;&#123;&#10; name &#61; optional&#40;string&#41;&#10; project_id &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [eventarc_triggers](variables.tf#L91) | Event arc triggers for different sources. | <code title="object&#40;&#123;&#10; audit_log &#61; optional&#40;map&#40;object&#40;&#123;&#10; method &#61; string&#10; service &#61; string&#10; &#125;&#41;&#41;, &#123;&#125;&#41;&#10; pubsub &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; service_account_email &#61; optional&#40;string&#41;&#10; service_account_create &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam](variables.tf#L105) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [ingress_settings](variables.tf#L111) | Ingress settings. | <code>string</code> | | <code>null</code> |
| [labels](variables.tf#L117) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [prefix](variables.tf#L128) | Optional prefix used for resource names. | <code>string</code> | | <code>null</code> |
| [region](variables.tf#L143) | Region used for all resources. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [revision_annotations](variables.tf#L149) | Configure revision template annotations. | <code title="object&#40;&#123;&#10; autoscaling &#61; optional&#40;object&#40;&#123;&#10; max_scale &#61; number&#10; min_scale &#61; number&#10; &#125;&#41;&#41;&#10; cloudsql_instances &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; vpcaccess_connector &#61; optional&#40;string&#41;&#10; vpcaccess_egress &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [revision_name](variables.tf#L164) | Revision name. | <code>string</code> | | <code>null</code> |
| [service_account](variables.tf#L170) | Service account email. Unused if service account is auto-created. | <code>string</code> | | <code>null</code> |
| [service_account_create](variables.tf#L176) | Auto-create service account. | <code>bool</code> | | <code>false</code> |
| [timeout_seconds](variables.tf#L182) | Maximum duration the instance is allowed for responding to a request. | <code>number</code> | | <code>null</code> |
| [traffic](variables.tf#L188) | Traffic steering configuration. If revision name is null the latest revision will be used. | <code title="map&#40;object&#40;&#123;&#10; percent &#61; number&#10; latest &#61; optional&#40;bool&#41;&#10; tag &#61; optional&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [volumes](variables.tf#L199) | Named volumes in containers in name => attributes format. | <code title="map&#40;object&#40;&#123;&#10; secret_name &#61; string&#10; default_mode &#61; optional&#40;string&#41;&#10; items &#61; optional&#40;map&#40;object&#40;&#123;&#10; path &#61; string&#10; mode &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc_connector_create](variables.tf#L213) | Populate this to create a VPC connector. You can then refer to it in the template annotations. | <code title="object&#40;&#123;&#10; ip_cidr_range &#61; optional&#40;string&#41;&#10; vpc_self_link &#61; optional&#40;string&#41;&#10; machine_type &#61; optional&#40;string&#41;&#10; name &#61; optional&#40;string&#41;&#10; instances &#61; optional&#40;object&#40;&#123;&#10; max &#61; optional&#40;number&#41;&#10; min &#61; optional&#40;number&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; throughput &#61; optional&#40;object&#40;&#123;&#10; max &#61; optional&#40;number&#41;&#10; min &#61; optional&#40;number&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; subnet &#61; optional&#40;object&#40;&#123;&#10; name &#61; optional&#40;string&#41;&#10; project_id &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs

View File

@@ -35,6 +35,17 @@ locals {
"run.googleapis.com/ingress" = var.ingress_settings
}
)
_iam_run_invoker_members = concat(
lookup(var.iam, "roles/run.invoker", []),
var.eventarc_triggers.service_account_create ? ["serviceAccount:${local.trigger_service_account_email}"] : []
)
iam = merge(
var.iam,
length(local._iam_run_invoker_members) == 0 ? {} :
{
"roles/run.invoker" : local._iam_run_invoker_members
},
)
prefix = var.prefix == null ? "" : "${var.prefix}-"
revision_annotations = merge(
try(var.revision_annotations.autoscaling, null) == null ? {} : {
@@ -73,6 +84,17 @@ locals {
)
: var.service_account
)
trigger_service_account_email = (
var.eventarc_triggers.service_account_create
? (
length(google_service_account.trigger_service_account) > 0
? google_service_account.trigger_service_account[0].email
# : google_service_account.trigger_service_account[0].email # : null
: null
)
: var.eventarc_triggers.service_account_email
)
vpc_connector_create = var.vpc_connector_create != null
}
@@ -288,7 +310,7 @@ resource "google_cloud_run_service" "service" {
}
resource "google_cloud_run_service_iam_binding" "binding" {
for_each = var.iam
for_each = local.iam
project = google_cloud_run_service.service.project
location = google_cloud_run_service.service.location
service = google_cloud_run_service.service.name
@@ -326,6 +348,7 @@ resource "google_eventarc_trigger" "audit_log_triggers" {
region = google_cloud_run_service.service.location
}
}
service_account = local.trigger_service_account_email
}
resource "google_eventarc_trigger" "pubsub_triggers" {
@@ -348,4 +371,12 @@ resource "google_eventarc_trigger" "pubsub_triggers" {
region = google_cloud_run_service.service.location
}
}
service_account = local.trigger_service_account_email
}
resource "google_service_account" "trigger_service_account" {
count = var.eventarc_triggers.service_account_create ? 1 : 0 # coalesce(try(var.eventarc_triggers.service_account_create, false), false) ? 1 : 0
project = var.project_id
account_id = "tf-cr-trigger-${var.name}"
display_name = "Terraform trigger for Cloud Run ${var.name}."
}

View File

@@ -95,7 +95,9 @@ variable "eventarc_triggers" {
method = string
service = string
})), {})
pubsub = optional(map(string), {})
pubsub = optional(map(string), {})
service_account_email = optional(string)
service_account_create = optional(bool, false)
})
default = {}
}

View File

@@ -0,0 +1,22 @@
# 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_service.service: {}
module.cloud_run.google_eventarc_trigger.audit_log_triggers["setiampolicy"]:
service_account: cloud-run-trigger@my-project.iam.gserviceaccount.com
counts:
google_cloud_run_service: 1
google_eventarc_trigger: 1

View File

@@ -0,0 +1,35 @@
# 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_service.service: {}
module.cloud_run.google_cloud_run_service_iam_binding.binding["roles/run.invoker"]:
project: my-project
role: roles/run.invoker
service: hello
# members: ["known after apply"]
module.cloud_run.google_eventarc_trigger.pubsub_triggers["topic-1"]: {}
# service_account: known after apply
module.cloud_run.google_eventarc_trigger.pubsub_triggers["topic-2"]: {}
# service_account: known after apply
module.cloud_run.google_service_account.trigger_service_account[0]:
account_id: tf-cr-trigger-hello
display_name: Terraform trigger for Cloud Run hello.
project: my-project
counts:
google_cloud_run_service: 1
google_cloud_run_service_iam_binding: 1
google_eventarc_trigger: 2
google_service_account: 1