Add trigger SA for Cloud Run
This commit is contained in:
committed by
Wiktor Niesiobędzki
parent
91daad5570
commit
3ac6ceac1e
@@ -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(object({ image = string args = optional(list(string)) command = optional(list(string)) env = optional(map(string), {}) env_from_key = optional(map(object({ key = string name = string })), {}) liveness_probe = optional(object({ action = object({ grcp = optional(object({ port = optional(number) service = optional(string) })) http_get = optional(object({ http_headers = optional(map(string), {}) path = optional(string) })) }) failure_threshold = optional(number) initial_delay_seconds = optional(number) period_seconds = optional(number) timeout_seconds = optional(number) })) ports = optional(map(object({ container_port = optional(number) name = optional(string) protocol = optional(string) })), {}) resources = optional(object({ limits = optional(object({ cpu = string memory = string })) requests = optional(object({ cpu = string memory = string })) })) startup_probe = optional(object({ action = object({ grcp = optional(object({ port = optional(number) service = optional(string) })) http_get = optional(object({ http_headers = optional(map(string), {}) path = optional(string) })) tcp_socket = optional(object({ port = optional(number) })) }) failure_threshold = optional(number) initial_delay_seconds = optional(number) period_seconds = optional(number) timeout_seconds = optional(number) })) volume_mounts = optional(map(string), {}) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [eventarc_triggers](variables.tf#L91) | Event arc triggers for different sources. | <code title="object({ audit_log = optional(map(object({ method = string service = string })), {}) pubsub = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L103) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [ingress_settings](variables.tf#L109) | Ingress settings. | <code>string</code> | | <code>null</code> |
|
||||
| [labels](variables.tf#L115) | Resource labels. | <code>map(string)</code> | | <code>{}</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>"europe-west1"</code> |
|
||||
| [revision_annotations](variables.tf#L147) | Configure revision template annotations. | <code title="object({ autoscaling = optional(object({ max_scale = number min_scale = number })) cloudsql_instances = optional(list(string), []) vpcaccess_connector = optional(string) vpcaccess_egress = optional(string) })">object({…})</code> | | <code>{}</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(object({ percent = number latest = optional(bool) tag = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [volumes](variables.tf#L197) | Named volumes in containers in name => attributes format. | <code title="map(object({ secret_name = string default_mode = optional(string) items = optional(map(object({ path = string mode = optional(string) }))) }))">map(object({…}))</code> | | <code>{}</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({ ip_cidr_range = optional(string) vpc_self_link = optional(string) machine_type = optional(string) name = optional(string) instances = optional(object({ max = optional(number) min = optional(number) }), {}) throughput = optional(object({ max = optional(number) min = optional(number) }), {}) subnet = optional(object({ name = optional(string) project_id = optional(string) }), {}) })">object({…})</code> | | <code>null</code> |
|
||||
| [eventarc_triggers](variables.tf#L91) | Event arc triggers for different sources. | <code title="object({ audit_log = optional(map(object({ method = string service = string })), {}) pubsub = optional(map(string), {}) service_account_email = optional(string) service_account_create = optional(bool, false) })">object({…})</code> | | <code>{}</code> |
|
||||
| [iam](variables.tf#L105) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [ingress_settings](variables.tf#L111) | Ingress settings. | <code>string</code> | | <code>null</code> |
|
||||
| [labels](variables.tf#L117) | Resource labels. | <code>map(string)</code> | | <code>{}</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>"europe-west1"</code> |
|
||||
| [revision_annotations](variables.tf#L149) | Configure revision template annotations. | <code title="object({ autoscaling = optional(object({ max_scale = number min_scale = number })) cloudsql_instances = optional(list(string), []) vpcaccess_connector = optional(string) vpcaccess_egress = optional(string) })">object({…})</code> | | <code>{}</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(object({ percent = number latest = optional(bool) tag = optional(string) }))">map(object({…}))</code> | | <code>{}</code> |
|
||||
| [volumes](variables.tf#L199) | Named volumes in containers in name => attributes format. | <code title="map(object({ secret_name = string default_mode = optional(string) items = optional(map(object({ path = string mode = optional(string) }))) }))">map(object({…}))</code> | | <code>{}</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({ ip_cidr_range = optional(string) vpc_self_link = optional(string) machine_type = optional(string) name = optional(string) instances = optional(object({ max = optional(number) min = optional(number) }), {}) throughput = optional(object({ max = optional(number) min = optional(number) }), {}) subnet = optional(object({ name = optional(string) project_id = optional(string) }), {}) })">object({…})</code> | | <code>null</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
|
||||
@@ -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}."
|
||||
}
|
||||
|
||||
@@ -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 = {}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user