2021-10-31 14:40:28 -07:00
# Cloud Run Module
2023-04-01 05:06:29 -07:00
Cloud Run management, with support for IAM roles, revision annotations and optional Eventarc trigger creation.
2021-10-31 14:40:28 -07:00
## Examples
2023-07-28 06:43:51 -07:00
<!-- BEGIN TOC -->
- [Examples ](#examples )
- [IAM and environment variables ](#iam-and-environment-variables )
- [Mounting secrets as volumes ](#mounting-secrets-as-volumes )
- [Revision annotations ](#revision-annotations )
2023-08-09 14:04:16 -07:00
- [Second generation execution environment ](#second-generation-execution-environment )
2023-07-28 06:43:51 -07:00
- [VPC Access Connector creation ](#vpc-access-connector-creation )
- [Traffic split ](#traffic-split )
- [Eventarc triggers ](#eventarc-triggers )
- [PubSub ](#pubsub )
- [Audit logs ](#audit-logs )
- [Using custom service accounts for triggers ](#using-custom-service-accounts-for-triggers )
- [Service account ](#service-account )
- [Variables ](#variables )
- [Outputs ](#outputs )
<!-- END TOC -->
2021-11-01 12:34:23 -07:00
2023-04-01 05:06:29 -07:00
### IAM and environment variables
IAM bindings support the usual syntax. Container environment values can be declared as key-value strings or as references to Secret Manager secrets. Both can be combined as long as there's no duplication of keys:
2021-11-01 12:34:23 -07:00
```hcl
2023-11-17 03:49:26 -08:00
module "secret-manager" {
source = "./fabric/modules/secret-manager"
project_id = var.project_id
secrets = {
credentials = {}
}
iam = {
credentials = {
"roles/secretmanager.secretAccessor" = [module.cloud_run.service_account_iam_email]
}
}
}
2021-11-01 12:34:23 -07:00
module "cloud_run" {
2022-09-06 08:46:09 -07:00
source = "./fabric/modules/cloud-run"
2023-10-20 00:59:52 -07:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2021-11-01 12:34:23 -07:00
name = "hello"
2023-04-01 05:06:29 -07:00
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
2022-12-16 03:53:56 -08:00
env = {
2023-04-01 05:06:29 -07:00
VAR1 = "VALUE1"
VAR2 = "VALUE2"
}
env_from = {
SECRET1 = {
2023-11-17 03:49:26 -08:00
name = module.secret-manager.ids["credentials"]
key = "latest"
2023-04-01 05:06:29 -07:00
}
2021-11-03 15:48:01 -07:00
}
2021-11-01 12:34:23 -07:00
}
2023-04-01 05:06:29 -07:00
}
iam = {
"roles/run.invoker" = ["allUsers"]
}
2023-11-17 03:49:26 -08:00
service_account_create = true
2021-11-01 12:34:23 -07:00
}
2023-11-17 03:49:26 -08:00
# tftest modules=2 resources=5 inventory=simple.yaml e2e
2021-11-01 12:34:23 -07:00
```
2023-04-01 05:06:29 -07:00
### Mounting secrets as volumes
2021-11-01 12:34:23 -07:00
```hcl
2023-11-17 03:49:26 -08:00
module "secret-manager" {
source = "./fabric/modules/secret-manager"
project_id = var.project_id
secrets = {
credentials = {}
}
versions = {
credentials = {
v1 = { enabled = true, data = "foo bar baz" }
}
}
iam = {
credentials = {
"roles/secretmanager.secretAccessor" = [module.cloud_run.service_account_iam_email]
}
}
}
2021-11-01 12:34:23 -07:00
module "cloud_run" {
2022-09-06 08:46:09 -07:00
source = "./fabric/modules/cloud-run"
2023-04-01 05:06:29 -07:00
project_id = var.project_id
2021-11-01 12:34:23 -07:00
name = "hello"
2023-04-01 05:06:29 -07:00
region = var.region
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
volume_mounts = {
"credentials" = "/credentials"
}
}
}
2023-11-17 03:49:26 -08:00
service_account_create = true
2023-04-01 05:06:29 -07:00
volumes = {
credentials = {
2023-11-17 03:49:26 -08:00
name = module.secret-manager.secrets["credentials"].name
secret_name = "credentials" # TODO: module.secret-manager.secrets["credentials"].name
2023-04-01 05:06:29 -07:00
items = {
2023-11-17 03:49:26 -08:00
latest = { path = "v1.txt" }
2021-11-01 12:34:23 -07:00
}
}
2023-04-01 05:06:29 -07:00
}
2021-11-01 12:34:23 -07:00
}
2023-11-17 03:49:26 -08:00
# tftest modules=2 resources=5 inventory=secrets.yaml e2e
2021-11-01 12:34:23 -07:00
```
2023-04-01 05:06:29 -07:00
### Revision annotations
Annotations can be specified via the `revision_annotations` variable:
2021-11-01 12:34:23 -07:00
```hcl
module "cloud_run" {
2023-04-01 05:06:29 -07:00
source = "./fabric/modules/cloud-run"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-04-01 05:06:29 -07:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
2021-11-01 12:34:23 -07:00
}
2023-04-01 05:06:29 -07:00
}
revision_annotations = {
autoscaling = {
max_scale = 10
min_scale = 1
2021-11-01 12:34:23 -07:00
}
2023-04-01 05:06:29 -07:00
cloudsql_unstances = ["sql-0", "sql-1"]
vpcaccess_connector = "foo"
vpcaccess_egress = "all-traffic"
}
}
# tftest modules=1 resources=1 inventory=revision-annotations.yaml
```
2023-08-09 14:04:16 -07:00
### Second generation execution environment
Second generation execution environment (gen2) can be enabled by setting the `gen2_execution_environment` variable to true:
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-08-09 14:04:16 -07:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
gen2_execution_environment = true
}
2023-11-17 03:49:26 -08:00
# tftest modules=1 resources=1 inventory=gen2.yaml e2e
2023-08-09 14:04:16 -07:00
```
2023-04-01 05:06:29 -07:00
### VPC Access Connector creation
2023-05-13 20:51:46 -07:00
If creation of a [VPC Access Connector ](https://cloud.google.com/vpc/docs/serverless-vpc-access ) is required, use the `vpc_connector_create` variable which also support optional attributes for number of instances, machine type, and throughput (not shown here). The annotation to use the connector will be added automatically.
2023-04-01 05:06:29 -07:00
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-04-01 05:06:29 -07:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
vpc_connector_create = {
2023-11-17 03:49:26 -08:00
ip_cidr_range = "10.10.10.0/28"
vpc_self_link = var.vpc.self_link
2023-04-01 05:06:29 -07:00
}
2021-11-01 12:34:23 -07:00
}
2023-11-17 03:49:26 -08:00
# tftest modules=1 resources=2 inventory=connector.yaml e2e
2021-11-01 12:34:23 -07:00
```
2023-05-05 10:38:34 -07:00
Note that if you are using Shared VPC you need to specify a subnet:
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-05-05 10:38:34 -07:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
vpc_connector_create = {
subnet = {
name = "subnet-vpc-access"
project_id = "host-project"
}
}
}
# tftest modules=1 resources=2 inventory=connector-shared.yaml
```
2021-10-31 14:40:28 -07:00
### Traffic split
This deploys a Cloud Run service with traffic split between two revisions.
```hcl
module "cloud_run" {
2022-12-16 03:53:56 -08:00
source = "./fabric/modules/cloud-run"
2023-11-17 03:49:26 -08:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2022-12-16 03:53:56 -08:00
name = "hello"
2021-10-31 14:40:28 -07:00
revision_name = "green"
2023-04-01 05:06:29 -07:00
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
2021-10-31 14:40:28 -07:00
traffic = {
2023-04-01 05:06:29 -07:00
blue = { percent = 25 }
green = { percent = 75 }
2021-10-31 14:40:28 -07:00
}
}
2023-04-01 05:06:29 -07:00
# tftest modules=1 resources=1 inventory=traffic.yaml
2021-10-31 14:40:28 -07:00
```
2023-04-01 05:06:29 -07:00
### Eventarc triggers
#### PubSub
2021-10-31 14:40:28 -07:00
This deploys a Cloud Run service that will be triggered when messages are published to Pub/Sub topics.
```hcl
2023-11-17 03:49:26 -08:00
module "pubsub" {
source = "./fabric/modules/pubsub"
project_id = var.project_id
name = "pubsub_sink"
}
2021-10-31 14:40:28 -07:00
module "cloud_run" {
2022-09-06 08:46:09 -07:00
source = "./fabric/modules/cloud-run"
2023-11-17 03:49:26 -08:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2021-10-31 14:40:28 -07:00
name = "hello"
2023-04-01 05:06:29 -07:00
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
pubsub = {
2023-11-17 03:49:26 -08:00
topic-1 = module.pubsub.id
2023-04-01 05:06:29 -07:00
}
}
2021-10-31 14:40:28 -07:00
}
2023-11-17 03:49:26 -08:00
# tftest modules=2 resources=3 inventory=eventarc.yaml e2e
2021-10-31 14:40:28 -07:00
```
2023-04-01 05:06:29 -07:00
#### Audit logs
2021-10-31 14:40:28 -07:00
This deploys a Cloud Run service that will be triggered when specific log events are written to Google Cloud audit logs.
2021-11-01 12:05:04 -07:00
```hcl
2023-11-17 03:49:26 -08:00
module "sa" {
source = "./fabric/modules/iam-service-account"
project_id = var.project_id
name = "eventarc-trigger"
iam_project_roles = {
(var.project_id) = ["roles/eventarc.eventReceiver"]
}
}
2021-10-31 14:40:28 -07:00
module "cloud_run" {
2022-09-06 08:46:09 -07:00
source = "./fabric/modules/cloud-run"
2023-11-17 03:49:26 -08:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2021-10-31 14:40:28 -07:00
name = "hello"
2023-04-01 05:06:29 -07:00
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
audit_log = {
setiampolicy = {
method = "SetIamPolicy"
service = "cloudresourcemanager.googleapis.com"
}
2021-10-31 14:40:28 -07:00
}
2023-11-17 03:49:26 -08:00
service_account_email = module.sa.email
}
iam = {
"roles/run.invoker" = [module.sa.iam_email]
2023-04-01 05:06:29 -07:00
}
2021-10-31 14:40:28 -07:00
}
2023-11-18 02:36:30 -08:00
# tftest modules=2 resources=5 inventory=audit-logs.yaml
2021-11-01 12:05:04 -07:00
```
2021-10-31 14:40:28 -07:00
2023-05-30 07:49:14 -07:00
#### 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.
2023-11-17 03:49:26 -08:00
For example using provided service account refer to [Audit logs ](#audit-logs ) example.
2023-05-30 07:49:14 -07:00
Example using automatically created service account:
2023-08-20 00:44:20 -07:00
2023-05-30 07:49:14 -07:00
```hcl
2023-11-17 03:49:26 -08:00
module "pubsub" {
source = "./fabric/modules/pubsub"
project_id = var.project_id
name = "pubsub_sink"
}
2023-05-30 07:49:14 -07:00
module "cloud_run" {
source = "./fabric/modules/cloud-run"
2023-11-17 03:49:26 -08:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-05-30 07:49:14 -07:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
pubsub = {
2023-11-17 03:49:26 -08:00
topic-1 = module.pubsub.id
2023-05-30 07:49:14 -07:00
}
service_account_create = true
}
}
2023-11-17 03:49:26 -08:00
# tftest modules=2 resources=5 inventory=trigger-service-account.yaml e2e
2023-05-30 07:49:14 -07:00
```
2023-04-01 05:06:29 -07:00
### Service account
2021-10-31 14:40:28 -07:00
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).
```hcl
module "cloud_run" {
2022-09-06 08:46:09 -07:00
source = "./fabric/modules/cloud-run"
2023-11-17 03:49:26 -08:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2021-10-31 14:40:28 -07:00
name = "hello"
2023-04-01 05:06:29 -07:00
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
2021-10-31 14:40:28 -07:00
service_account_create = true
}
2023-11-17 03:49:26 -08:00
# tftest modules=1 resources=2 inventory=service-account.yaml e2e
2021-10-31 14:40:28 -07:00
```
To use an externally managed service account, pass its email in `service_account` and leave `service_account_create` to `false` (the default).
```hcl
module "cloud_run" {
2022-09-06 08:46:09 -07:00
source = "./fabric/modules/cloud-run"
2023-11-17 03:49:26 -08:00
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2021-10-31 14:40:28 -07:00
name = "hello"
2023-04-01 05:06:29 -07:00
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
2023-11-17 03:49:26 -08:00
service_account = var.service_account.email
2021-10-31 14:40:28 -07:00
}
2023-11-17 03:49:26 -08:00
# tftest modules=1 resources=1 inventory=service-account-external.yaml e2e
2021-10-31 14:40:28 -07:00
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
2021-12-20 23:51:51 -08:00
|---|---|:---:|:---:|:---:|
2023-11-17 03:49:26 -08:00
| [name ](variables.tf#L144 ) | Name used for cloud run service. | < code > string</ code > | ✓ | |
| [project_id ](variables.tf#L159 ) | Project id used for all resources. | < code > string</ code > | ✓ | |
2024-01-24 02:23:40 -08:00
| [region ](variables.tf#L164 ) | Region used for all resources. | < code > string</ code > | ✓ | |
2023-04-01 05:06:29 -07:00
| [container_concurrency ](variables.tf#L18 ) | Maximum allowed in-flight (concurrent) requests per container of the revision. | < code > string</ code > | | < code > null</ code > |
2023-08-30 04:16:21 -07:00
| [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({ grpc = 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({ grpc = 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 > |
2023-05-30 07:49:14 -07:00
| [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 > |
2023-11-17 03:49:26 -08:00
| [gen2_execution_environment ](variables.tf#L113 ) | Use second generation execution environment. | < code > bool</ code > | | < code > false</ code > |
| [iam ](variables.tf#L119 ) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | < code > map( list( string)) </ code > | | < code > {} </ code > |
| [ingress_settings ](variables.tf#L125 ) | Ingress settings. | < code > string</ code > | | < code > null</ code > |
| [labels ](variables.tf#L138 ) | Resource labels. | < code > map( string) </ code > | | < code > {} </ code > |
| [prefix ](variables.tf#L149 ) | Optional prefix used for resource names. | < code > string</ code > | | < code > null</ code > |
2024-01-24 02:23:40 -08:00
| [revision_annotations ](variables.tf#L169 ) | 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#L184 ) | Revision name. | < code > string</ code > | | < code > null</ code > |
| [service_account ](variables.tf#L190 ) | Service account email. Unused if service account is auto-created. | < code > string</ code > | | < code > null</ code > |
| [service_account_create ](variables.tf#L196 ) | Auto-create service account. | < code > bool</ code > | | < code > false</ code > |
| [startup_cpu_boost ](variables.tf#L202 ) | Enable startup cpu boost. | < code > bool</ code > | | < code > false</ code > |
| [timeout_seconds ](variables.tf#L208 ) | Maximum duration the instance is allowed for responding to a request. | < code > number</ code > | | < code > null</ code > |
| [traffic ](variables.tf#L214 ) | 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#L225 ) | 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#L239 ) | 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 > |
2021-10-31 14:40:28 -07:00
## Outputs
| name | description | sensitive |
|---|---|:---:|
2023-06-02 07:07:22 -07:00
| [id ](outputs.tf#L18 ) | Fully qualified service id. | |
| [service ](outputs.tf#L23 ) | Cloud Run service. | |
| [service_account ](outputs.tf#L28 ) | Service account resource. | |
| [service_account_email ](outputs.tf#L33 ) | Service account email. | |
| [service_account_iam_email ](outputs.tf#L38 ) | Service account email. | |
| [service_name ](outputs.tf#L46 ) | Cloud Run service name. | |
| [vpc_connector ](outputs.tf#L52 ) | VPC connector resource if created. | |
2021-10-31 14:40:28 -07:00
<!-- END TFDOC -->