Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 63 additions & 18 deletions modules/cloud-run-v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Cloud Run Services and Jobs, with support for IAM roles and Eventarc trigger cre
- [Creating Cloud Run Jobs](#creating-cloud-run-jobs)
- [Tag bindings](#tag-bindings)
- [IAP Configuration](#iap-configuration)
- [Binary Authorization](#binary-authorization)
- [Adding GPUs](#adding-gpus)
- [Variables](#variables)
- [Outputs](#outputs)
Expand Down Expand Up @@ -881,6 +882,49 @@ module "cloud_run" {
# tftest inventory=iap.yaml e2e
```

## Binary Authorization

Binary Authorization can be enabled on services, jobs and worker pools. Setting `use_default = true` opts the resource into the [project default policy](https://cloud.google.com/binary-authorization/docs/run/enabling-binauthz-cloud-run); use `policy` instead to attach a custom Cloud Run Binary Authorization policy by its full resource path. `breakglass_justification` bypasses Binary Authorization checks for the current revision and emits a high-severity audit log entry — only set it for ad-hoc breakglass deploys.

```hcl
module "cloud_run" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
name = "example-binauthz"
region = var.region
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
binary_authorization = {
use_default = true
}
deletion_protection = false
}
# tftest inventory=binary-authorization.yaml e2e
```

```hcl
module "job" {
source = "./fabric/modules/cloud-run-v2"
project_id = var.project_id
name = "example-binauthz-job"
region = var.region
type = "JOB"
containers = {
hello = {
image = "us-docker.pkg.dev/cloudrun/container/hello"
}
}
binary_authorization = {
policy = "projects/${var.project_id}/platforms/cloudRun/policies/example-policy"
}
deletion_protection = false
}
# tftest inventory=binary-authorization-job.yaml
```

## Adding GPUs

GPU support is available for all types of Cloud Run resources: jobs, services and worker pools.
Expand Down Expand Up @@ -981,26 +1025,27 @@ module "worker" {

| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L182) | Name used for Cloud Run service. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L187) | Project id used for all resources. | <code>string</code> | ✓ | |
| [region](variables.tf#L192) | Region used for all resources. | <code>string</code> | ✓ | |
| [containers](variables.tf#L17) | Containers in name => attributes format. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [context](variables.tf#L97) | Context-specific interpolations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [deletion_protection](variables.tf#L119) | Deletion protection setting for this Cloud Run service. | <code>string</code> | | <code>null</code> |
| [encryption_key](variables.tf#L125) | The full resource name of the Cloud KMS CryptoKey. | <code>string</code> | | <code>null</code> |
| [iam](variables.tf#L131) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [job_config](variables.tf#L137) | Cloud Run Job specific configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [labels](variables.tf#L152) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [launch_stage](variables.tf#L158) | The launch stage as defined by Google Cloud Platform Launch Stages. | <code>string</code> | | <code>null</code> |
| [managed_revision](variables.tf#L175) | Whether the Terraform module should control the deployment of revisions. | <code>bool</code> | | <code>true</code> |
| [revision](variables.tf#L197) | Revision template configurations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [name](variables.tf#L214) | Name used for Cloud Run service. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L219) | Project id used for all resources. | <code>string</code> | ✓ | |
| [region](variables.tf#L224) | Region used for all resources. | <code>string</code> | ✓ | |
| [binary_authorization](variables.tf#L17) | Binary Authorization configuration. Applies to services, jobs and worker pools. Set `use_default = true` to enforce the project default policy, or `policy` to a custom Cloud Run policy resource path. `breakglass_justification` bypasses Binary Authorization checks for the resource and emits a high-severity audit log entry. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [containers](variables.tf#L49) | Containers in name => attributes format. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [context](variables.tf#L129) | Context-specific interpolations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [deletion_protection](variables.tf#L151) | Deletion protection setting for this Cloud Run service. | <code>string</code> | | <code>null</code> |
| [encryption_key](variables.tf#L157) | The full resource name of the Cloud KMS CryptoKey. | <code>string</code> | | <code>null</code> |
| [iam](variables.tf#L163) | IAM bindings for Cloud Run service in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [job_config](variables.tf#L169) | Cloud Run Job specific configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [labels](variables.tf#L184) | Resource labels. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [launch_stage](variables.tf#L190) | The launch stage as defined by Google Cloud Platform Launch Stages. | <code>string</code> | | <code>null</code> |
| [managed_revision](variables.tf#L207) | Whether the Terraform module should control the deployment of revisions. | <code>bool</code> | | <code>true</code> |
| [revision](variables.tf#L229) | Revision template configurations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [service_account_config](variables-serviceaccount.tf#L17) | Service account configurations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [service_config](variables.tf#L264) | Cloud Run service specific configuration options. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_bindings](variables.tf#L327) | Tag bindings for this service, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [type](variables.tf#L334) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | <code>string</code> | | <code>&#34;SERVICE&#34;</code> |
| [volumes](variables.tf#L344) | Named volumes in containers in name => attributes format. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [service_config](variables.tf#L296) | Cloud Run service specific configuration options. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_bindings](variables.tf#L359) | Tag bindings for this service, in key => tag value id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [type](variables.tf#L366) | Type of Cloud Run resource to deploy: JOB, SERVICE or WORKERPOOL. | <code>string</code> | | <code>&#34;SERVICE&#34;</code> |
| [volumes](variables.tf#L376) | Named volumes in containers in name => attributes format. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [vpc_connector_create](variables-vpcconnector.tf#L17) | VPC connector network configuration. Must be provided if new VPC connector is being created. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [workerpool_config](variables.tf#L378) | Cloud Run Worker Pool specific configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [workerpool_config](variables.tf#L410) | Cloud Run Worker Pool specific configuration. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |

## Outputs

Expand Down
10 changes: 10 additions & 0 deletions modules/cloud-run-v2/job-managed.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ resource "google_cloud_run_v2_job" "job" {
labels = var.labels
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection

dynamic "binary_authorization" {
for_each = var.binary_authorization == null ? [] : [""]
content {
breakglass_justification = var.binary_authorization.breakglass_justification
policy = var.binary_authorization.policy
use_default = var.binary_authorization.use_default
}
}

template {
labels = var.revision.labels
task_count = var.job_config.task_count
Expand Down
10 changes: 10 additions & 0 deletions modules/cloud-run-v2/job-unmanaged.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ resource "google_cloud_run_v2_job" "job_unmanaged" {
labels = var.labels
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection

dynamic "binary_authorization" {
for_each = var.binary_authorization == null ? [] : [""]
content {
breakglass_justification = var.binary_authorization.breakglass_justification
policy = var.binary_authorization.policy
use_default = var.binary_authorization.use_default
}
}

template {
labels = var.revision.labels
task_count = var.job_config.task_count
Expand Down
9 changes: 9 additions & 0 deletions modules/cloud-run-v2/service-managed.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ resource "google_cloud_run_v2_service" "service" {
deletion_protection = var.deletion_protection
iap_enabled = var.service_config.iap_config != null

dynamic "binary_authorization" {
for_each = var.binary_authorization == null ? [] : [""]
content {
breakglass_justification = var.binary_authorization.breakglass_justification
policy = var.binary_authorization.policy
use_default = var.binary_authorization.use_default
}
}

template {
labels = var.revision.labels
encryption_key = var.encryption_key
Expand Down
9 changes: 9 additions & 0 deletions modules/cloud-run-v2/service-unmanaged.tf
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ resource "google_cloud_run_v2_service" "service_unmanaged" {
deletion_protection = var.deletion_protection
iap_enabled = var.service_config.iap_config != null

dynamic "binary_authorization" {
for_each = var.binary_authorization == null ? [] : [""]
content {
breakglass_justification = var.binary_authorization.breakglass_justification
policy = var.binary_authorization.policy
use_default = var.binary_authorization.use_default
}
}

template {
labels = var.revision.labels
encryption_key = var.encryption_key
Expand Down
32 changes: 32 additions & 0 deletions modules/cloud-run-v2/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,38 @@
* limitations under the License.
*/

variable "binary_authorization" {
description = "Binary Authorization configuration. Applies to services, jobs and worker pools. Set `use_default = true` to enforce the project default policy, or `policy` to a custom Cloud Run policy resource path. `breakglass_justification` bypasses Binary Authorization checks for the resource and emits a high-severity audit log entry."
type = object({
breakglass_justification = optional(string)
policy = optional(string)
use_default = optional(bool, false)
})
default = null
validation {
condition = (
var.binary_authorization == null
? true
: (
var.binary_authorization.use_default
|| var.binary_authorization.policy != null
)
)
error_message = "Either binary_authorization.use_default must be true or binary_authorization.policy must be set."
}
validation {
condition = (
var.binary_authorization == null
? true
: !(
var.binary_authorization.use_default
&& var.binary_authorization.policy != null
)
)
error_message = "binary_authorization.use_default and binary_authorization.policy are mutually exclusive."
}
}

variable "containers" {
description = "Containers in name => attributes format."
type = map(object({
Expand Down
9 changes: 9 additions & 0 deletions modules/cloud-run-v2/workerpool-managed.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ resource "google_cloud_run_v2_worker_pool" "default_managed" {
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection

dynamic "binary_authorization" {
for_each = var.binary_authorization == null ? [] : [""]
content {
breakglass_justification = var.binary_authorization.breakglass_justification
policy = var.binary_authorization.policy
use_default = var.binary_authorization.use_default
}
}

dynamic "scaling" {
for_each = var.workerpool_config.scaling == null ? [] : [""]
content {
Expand Down
9 changes: 9 additions & 0 deletions modules/cloud-run-v2/workerpool-unmanaged.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ resource "google_cloud_run_v2_worker_pool" "default_unmanaged" {
launch_stage = var.launch_stage
deletion_protection = var.deletion_protection

dynamic "binary_authorization" {
for_each = var.binary_authorization == null ? [] : [""]
content {
breakglass_justification = var.binary_authorization.breakglass_justification
policy = var.binary_authorization.policy
use_default = var.binary_authorization.use_default
}
}

dynamic "scaling" {
for_each = var.workerpool_config.scaling == null ? [] : [""]
content {
Expand Down
87 changes: 87 additions & 0 deletions tests/modules/cloud_run_v2/examples/binary-authorization-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Copyright 2026 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
#
# https://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.job.google_cloud_run_v2_job.job[0]:
annotations: null
binary_authorization:
- breakglass_justification: null
policy: projects/project-id/platforms/cloudRun/policies/example-policy
use_default: false
client: null
client_version: null
deletion_policy: DELETE
deletion_protection: false
effective_labels:
goog-terraform-provisioned: 'true'
labels: null
location: europe-west8
name: example-binauthz-job
project: project-id
run_execution_token: null
start_execution_token: null
template:
- annotations: null
labels: null
template:
- containers:
- args: null
command: null
depends_on: null
env: []
image: us-docker.pkg.dev/cloudrun/container/hello
name: hello
ports: []
volume_mounts: []
working_dir: null
encryption_key: null
gpu_zonal_redundancy_disabled: null
max_retries: 3
node_selector: []
service_account: example-binauthz-job@project-id.iam.gserviceaccount.com
volumes: []
vpc_access: []
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
module.job.google_project_iam_member.default["roles/logging.logWriter"]:
condition: []
member: serviceAccount:example-binauthz-job@project-id.iam.gserviceaccount.com
project: project-id
role: roles/logging.logWriter
module.job.google_project_iam_member.default["roles/monitoring.metricWriter"]:
condition: []
member: serviceAccount:example-binauthz-job@project-id.iam.gserviceaccount.com
project: project-id
role: roles/monitoring.metricWriter
module.job.google_service_account.service_account[0]:
account_id: example-binauthz-job
create_ignore_already_exists: null
deletion_policy: DELETE
description: null
disabled: false
display_name: example-binauthz-job
email: example-binauthz-job@project-id.iam.gserviceaccount.com
member: serviceAccount:example-binauthz-job@project-id.iam.gserviceaccount.com
project: project-id
timeouts: null

counts:
google_cloud_run_v2_job: 1
google_project_iam_member: 2
google_service_account: 1
modules: 1
resources: 4

outputs: {}
Loading
Loading