2023-12-21 13:09:36 -08:00
# Cloud Run Module
2024-02-18 05:57:34 -08:00
Cloud Run Services and Jobs, with support for IAM roles and Eventarc trigger creation.
2023-12-21 13:09:36 -08:00
<!-- BEGIN TOC -->
- [Examples ](#examples )
- [IAM and environment variables ](#iam-and-environment-variables )
- [Mounting secrets as volumes ](#mounting-secrets-as-volumes )
- [Beta features ](#beta-features )
- [VPC Access Connector ](#vpc-access-connector )
- [Eventarc triggers ](#eventarc-triggers )
- [PubSub ](#pubsub )
- [Audit logs ](#audit-logs )
- [Using custom service accounts for triggers ](#using-custom-service-accounts-for-triggers )
2023-12-25 00:42:22 -08:00
- [Cloud Run Service Account ](#cloud-run-service-account )
2024-02-18 05:57:34 -08:00
- [Creating Cloud Run Jobs ](#creating-cloud-run-jobs )
2023-12-21 13:09:36 -08:00
- [Variables ](#variables )
- [Outputs ](#outputs )
2024-02-18 05:57:34 -08:00
- [Fixtures ](#fixtures )
2023-12-21 13:09:36 -08:00
<!-- END TOC -->
2024-02-18 05:57:34 -08:00
## Examples
2023-12-21 13:09:36 -08: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 is no duplication of keys:
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
name = "hello"
region = var.region
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
env = {
VAR1 = "VALUE1"
VAR2 = "VALUE2"
}
env_from_key = {
SECRET1 = {
2024-02-18 05:57:34 -08:00
secret = module.secret-manager.secrets["credentials"].name
version = module.secret-manager.version_versions["credentials:v1"]
2023-12-21 13:09:36 -08:00
}
}
}
}
iam = {
"roles/run.invoker" = ["allUsers"]
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=2 resources=5 fixtures=fixtures/secret-credentials.tf inventory=service-iam-env.yaml e2e
2023-12-21 13:09:36 -08:00
```
### Mounting secrets as volumes
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
name = "hello"
region = var.region
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
volume_mounts = {
"credentials" = "/credentials"
}
}
}
volumes = {
credentials = {
secret = {
2024-02-18 05:57:34 -08:00
name = module.secret-manager.secrets["credentials"].id
path = "my-secret"
version = "latest" # TODO: should be optional, but results in API error
2023-12-21 13:09:36 -08:00
}
}
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=2 resources=4 fixtures=fixtures/secret-credentials.tf inventory=service-volume-secretes.yaml e2e
2023-12-21 13:09:36 -08:00
```
### Beta features
2023-12-25 00:39:52 -08:00
To use beta features like Direct VPC Egress, set the launch stage to a preview stage.
2023-12-21 13:09:36 -08:00
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
name = "hello"
region = var.region
launch_stage = "BETA"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
revision = {
gen2_execution_environment = true
max_instance_count = 20
vpc_access = {
egress = "ALL_TRAFFIC"
subnet = "default"
tags = ["tag1", "tag2", "tag3"]
}
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=1 resources=1 inventory=service-beta-features.yaml
2023-12-21 13:09:36 -08:00
```
### VPC Access Connector
2023-12-25 00:39:52 -08:00
You can use an existing [VPC Access Connector ](https://cloud.google.com/vpc/docs/serverless-vpc-access ) to connect to a VPC from Cloud Run.
2023-12-21 13:09:36 -08:00
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
revision = {
vpc_access = {
2024-02-18 05:57:34 -08:00
connector = google_vpc_access_connector.connector.id
2023-12-21 13:09:36 -08:00
egress = "ALL_TRAFFIC"
}
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=1 resources=2 fixtures=fixtures/vpc-connector.tf inventory=service-vpc-access-connector.yaml e2e
2023-12-21 13:09:36 -08:00
```
2023-12-25 00:39:52 -08:00
If creation of the VPC Access Connector is required, use the `vpc_connector_create` variable which also supports optional attributes like number of instances, machine type, or throughput. The connector will be used automatically.
2023-12-21 13:09:36 -08:00
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
vpc_connector_create = {
2024-02-18 05:57:34 -08:00
ip_cidr_range = "10.10.10.0/28"
network = var.vpc.self_link
2023-12-21 13:09:36 -08:00
instances = {
max = 10
min = 2
}
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=1 resources=2 inventory=service-vpc-access-connector-create.yaml e2e
2023-12-21 13:09:36 -08:00
```
Note that if you are using a Shared VPC for the connector, you need to specify a subnet and the host project if this is not where the Cloud Run service is deployed.
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
2024-02-18 05:57:34 -08:00
project_id = module.project-service.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
vpc_connector_create = {
machine_type = "e2-standard-4"
subnet = {
2024-02-18 05:57:34 -08:00
name = module.net-vpc-host.subnets["${var.region}/fixture-subnet-28"].name
project_id = module.project-host.project_id
2023-12-21 13:09:36 -08:00
}
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=4 resources=40 fixtures=fixtures/shared-vpc.tf inventory=service-vpc-access-connector-create-sharedvpc.yaml e2e
2023-12-21 13:09:36 -08:00
```
### Eventarc triggers
#### PubSub
This deploys a Cloud Run service that will be triggered when messages are published to Pub/Sub topics.
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
pubsub = {
2024-02-18 05:57:34 -08:00
topic-1 = module.pubsub.topic.name
2023-12-21 13:09:36 -08:00
}
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=2 resources=4 fixtures=fixtures/pubsub.tf inventory=service-eventarc-pubsub.yaml e2e
2023-12-21 13:09:36 -08:00
```
#### Audit logs
This deploys a Cloud Run service that will be triggered when specific log events are written to Google Cloud audit logs.
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
audit_log = {
setiampolicy = {
method = "SetIamPolicy"
service = "cloudresourcemanager.googleapis.com"
}
}
2024-02-18 05:57:34 -08:00
service_account_create = true
2023-12-21 13:09:36 -08:00
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=1 resources=4 inventory=service-eventarc-auditlogs-sa-create.yaml
2023-12-21 13:09:36 -08: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 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
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
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"
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=1 resources=2 inventory=service-eventarc-auditlogs-external-sa.yaml
2023-12-21 13:09:36 -08:00
```
Example using automatically created service account:
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
eventarc_triggers = {
pubsub = {
2024-02-18 05:57:34 -08:00
topic-1 = module.pubsub.topic.name
2023-12-21 13:09:36 -08:00
}
service_account_create = true
}
}
2024-02-18 05:57:34 -08:00
# tftest modules=2 resources=6 fixtures=fixtures/pubsub.tf inventory=service-eventarc-pubsub-sa-create.yaml e2e
2023-12-21 13:09:36 -08:00
```
2023-12-25 00:39:52 -08:00
### Cloud Run Service Account
2023-12-21 13:09:36 -08:00
To use a custom service account managed by the module, set `service_account_create` to `true` and leave `service_account` set to `null` (default).
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
service_account_create = true
}
2024-02-18 05:57:34 -08:00
# tftest modules=1 resources=2 inventory=service-sa-create.yaml e2e
2023-12-21 13:09:36 -08:00
```
To use an externally managed service account, use its email in `service_account` and leave `service_account_create` to `false` (default).
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
2024-01-24 02:23:40 -08:00
region = var.region
2023-12-21 13:09:36 -08:00
name = "hello"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
2024-02-18 05:57:34 -08:00
service_account = module.iam-service-account.email
2023-12-21 13:09:36 -08:00
}
2024-02-18 05:57:34 -08:00
# tftest modules=2 resources=2 fixtures=fixtures/iam-service-account.tf inventory=service-external-sa.yaml e2e
```
### Creating Cloud Run Jobs
To create a job instead of service set `create_job` to `true` . Jobs support all functions above apart from triggers.
Unsupported variables / attributes:
* ingress
* revision.gen2_execution_environment (they run by default in gen2)
* revision.name
* containers.liveness_probe
* containers.startup_probe
* containers.resources.cpu_idle
* containers.resources.startup_cpu_boost
```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
name = "hello"
region = var.region
create_job = true
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
env = {
VAR1 = "VALUE1"
VAR2 = "VALUE2"
}
}
}
iam = {
"roles/run.invoker" = ["group:${var.group_email}"]
}
}
# tftest modules=1 resources=2 inventory=job-iam-env.yaml e2e
2023-12-21 13:09:36 -08:00
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
2024-02-18 05:57:34 -08:00
| [name ](variables.tf#L147 ) | Name used for Cloud Run service. | < code > string</ code > | ✓ | |
| [project_id ](variables.tf#L162 ) | Project id used for all resources. | < code > string</ code > | ✓ | |
| [region ](variables.tf#L167 ) | Region used for all resources. | < code > string</ code > | ✓ | |
2023-12-21 13:09:36 -08:00
| [containers ](variables.tf#L17 ) | Containers in name => attributes format. | < code title = "map(object({ image = string command = optional(list(string)) args = optional(list(string)) env = optional(map(string)) env_from_key = optional(map(object({ secret = string version = string }))) liveness_probe = optional(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) }))) resources = optional(object({ limits = optional(object({ cpu = string memory = string })) cpu_idle = optional(bool) startup_cpu_boost = optional(bool) })) startup_probe = optional(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 > |
2024-02-18 05:57:34 -08:00
| [create_job ](variables.tf#L77 ) | Create Cloud Run Job instead of Service. | < code > bool</ code > | | < code > false</ code > |
| [eventarc_triggers ](variables.tf#L83 ) | 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#L101 ) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | < code > map( list( string)) </ code > | | < code > {} </ code > |
| [ingress ](variables.tf#L107 ) | Ingress settings. | < code > string</ code > | | < code > null</ code > |
| [labels ](variables.tf#L124 ) | Resource labels. | < code > map( string) </ code > | | < code > {} </ code > |
| [launch_stage ](variables.tf#L130 ) | The launch stage as defined by Google Cloud Platform Launch Stages. | < code > string</ code > | | < code > null</ code > |
| [prefix ](variables.tf#L152 ) | Optional prefix used for resource names. | < code > string</ code > | | < code > null</ code > |
| [revision ](variables.tf#L172 ) | Revision template configurations. | < code title = "object({ name = optional(string) gen2_execution_environment = optional(bool) max_concurrency = optional(number) max_instance_count = optional(number) min_instance_count = optional(number) vpc_access = optional(object({ connector = optional(string) egress = optional(string) subnet = optional(string) tags = optional(list(string)) })) timeout = optional(string) })" > object({…}) </ code > | | < code > {} </ code > |
| [service_account ](variables.tf#L199 ) | Service account email. Unused if service account is auto-created. | < code > string</ code > | | < code > null</ code > |
| [service_account_create ](variables.tf#L205 ) | Auto-create service account. | < code > bool</ code > | | < code > false</ code > |
| [volumes ](variables.tf#L211 ) | Named volumes in containers in name => attributes format. | < code title = "map(object({ secret = optional(object({ name = string default_mode = optional(string) path = optional(string) version = optional(string) mode = optional(string) })) cloud_sql_instances = optional(list(string)) empty_dir_size = optional(string) }))" > map( object({…})) </ code > | | < code > {} </ code > |
| [vpc_connector_create ](variables-vpcconnector.tf#L17 ) | Populate this to create a Serverless VPC Access connector. | < code title = "object({ ip_cidr_range = optional(string) machine_type = optional(string) name = optional(string) network = optional(string) instances = optional(object({ max = optional(number) min = optional(number) }), {}) throughput = optional(object({ max = optional(number, 1000) # workaround for a wrong default in provider min = optional(number) }), {}) subnet = optional(object({ name = optional(string) project_id = optional(string) }), {}) })" > object({…}) </ code > | | < code > null</ code > |
2023-12-21 13:09:36 -08:00
## Outputs
| name | description | sensitive |
|---|---|:---:|
2024-02-18 05:57:34 -08:00
| [id ](outputs.tf#L17 ) | Fully qualified job or service id. | |
| [job ](outputs.tf#L22 ) | Cloud Run Job. | |
| [service ](outputs.tf#L27 ) | Cloud Run Service. | |
| [service_account ](outputs.tf#L32 ) | Service account resource. | |
| [service_account_email ](outputs.tf#L37 ) | Service account email. | |
| [service_account_iam_email ](outputs.tf#L42 ) | Service account email. | |
| [service_name ](outputs.tf#L50 ) | Cloud Run service name. | |
| [vpc_connector ](outputs.tf#L55 ) | VPC connector resource if created. | |
## Fixtures
- [iam-service-account.tf ](../../tests/fixtures/iam-service-account.tf )
- [pubsub.tf ](../../tests/fixtures/pubsub.tf )
- [secret-credentials.tf ](../../tests/fixtures/secret-credentials.tf )
- [shared-vpc.tf ](../../tests/fixtures/shared-vpc.tf )
- [vpc-connector.tf ](../../tests/fixtures/vpc-connector.tf )
2023-12-21 13:09:36 -08:00
<!-- END TFDOC -->