From 75788a0547a522f43bf8bc67f92f41fa6391bc7b Mon Sep 17 00:00:00 2001 From: Loren Gordon <8457307+lorengordon@users.noreply.github.com> Date: Fri, 21 Aug 2026 09:28:27 -0700 Subject: [PATCH] feat(terraform): Exposes `invoker_iam_disabled` input to support environments enforcing DRS policy --- terraform/litellm/gcp/README.md | 18 +++++++++ terraform/litellm/gcp/cloudrun.tf | 39 ++++++++++++------- .../litellm/gcp/examples/default/main.tf | 2 + .../litellm/gcp/examples/default/variables.tf | 7 ++++ terraform/litellm/gcp/migrations.tf | 14 +++++++ terraform/litellm/gcp/variables.tf | 7 ++++ 6 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 terraform/litellm/gcp/migrations.tf diff --git a/terraform/litellm/gcp/README.md b/terraform/litellm/gcp/README.md index 88e9979148f..aab0af998bc 100644 --- a/terraform/litellm/gcp/README.md +++ b/terraform/litellm/gcp/README.md @@ -286,6 +286,7 @@ example files. cd terraform/litellm/gcp/examples/default cp terraform.tfvars.example terraform.tfvars # Edit: project, region, tenant, env, image_registry, proxy_config, gateway_extra_secrets. +# If your org enforces Domain Restricted Sharing (DRS), also set invoker_iam_disabled = true. terraform init terraform apply @@ -342,6 +343,23 @@ Set `allow_plaintext_lb = true` and leave `lb_domains = []`. Without the flag, plan fails with a clear error pointing at the precondition. Intended for short-lived trial / dev stacks only. +## Domain Restricted Sharing (DRS) + +Some organizations enforce Domain Restricted Sharing policies that reject +`allUsers` IAM members on Cloud Run. This module supports those environments +through the `invoker_iam_disabled` input. + +- `invoker_iam_disabled = true`: disables the Cloud Run invoker IAM check on + gateway/backend/ui services and skips the `allUsers` `run.invoker` bindings. +- `invoker_iam_disabled = false` (or unset): implements `allUsers` invoker + bindings so the load balancer can call the Cloud Run services. + +Example for DRS-constrained environments: + +```hcl +invoker_iam_disabled = true +``` + ## Using as a module The directory itself is a module with **no `provider` block** — the caller diff --git a/terraform/litellm/gcp/cloudrun.tf b/terraform/litellm/gcp/cloudrun.tf index 3340522734f..bdbcc13169c 100644 --- a/terraform/litellm/gcp/cloudrun.tf +++ b/terraform/litellm/gcp/cloudrun.tf @@ -195,11 +195,12 @@ resource "google_cloud_run_v2_service" "gateway" { } } - name = "${local.name}-gateway" - location = var.region - ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" - labels = local.labels - deletion_protection = false + name = "${local.name}-gateway" + location = var.region + ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" + labels = local.labels + invoker_iam_disabled = var.invoker_iam_disabled + deletion_protection = false template { service_account = google_service_account.runtime.email @@ -324,11 +325,12 @@ resource "google_cloud_run_v2_service" "backend" { } } - name = "${local.name}-backend" - location = var.region - ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" - labels = local.labels - deletion_protection = false + name = "${local.name}-backend" + location = var.region + ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" + labels = local.labels + invoker_iam_disabled = var.invoker_iam_disabled + deletion_protection = false template { service_account = google_service_account.runtime.email @@ -443,11 +445,12 @@ resource "google_cloud_run_v2_service" "backend" { # with zero IAM bindings, so a compromised UI container can't pivot to # Secret Manager / Cloud SQL via the metadata service. resource "google_cloud_run_v2_service" "ui" { - name = "${local.name}-ui" - location = var.region - ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" - labels = local.labels - deletion_protection = false + name = "${local.name}-ui" + location = var.region + ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER" + labels = local.labels + invoker_iam_disabled = var.invoker_iam_disabled + deletion_protection = false template { service_account = google_service_account.ui_runtime.email @@ -491,6 +494,8 @@ resource "google_cloud_run_v2_service" "ui" { # (LITELLM_MASTER_KEY); these IAM bindings just open up Cloud Run's invoker # gate so the LB request makes it to the container. resource "google_cloud_run_v2_service_iam_member" "gateway_allusers" { + count = var.invoker_iam_disabled == true ? 0 : 1 + project = var.project_id location = google_cloud_run_v2_service.gateway.location name = google_cloud_run_v2_service.gateway.name @@ -499,6 +504,8 @@ resource "google_cloud_run_v2_service_iam_member" "gateway_allusers" { } resource "google_cloud_run_v2_service_iam_member" "backend_allusers" { + count = var.invoker_iam_disabled == true ? 0 : 1 + project = var.project_id location = google_cloud_run_v2_service.backend.location name = google_cloud_run_v2_service.backend.name @@ -507,6 +514,8 @@ resource "google_cloud_run_v2_service_iam_member" "backend_allusers" { } resource "google_cloud_run_v2_service_iam_member" "ui_allusers" { + count = var.invoker_iam_disabled == true ? 0 : 1 + project = var.project_id location = google_cloud_run_v2_service.ui.location name = google_cloud_run_v2_service.ui.name diff --git a/terraform/litellm/gcp/examples/default/main.tf b/terraform/litellm/gcp/examples/default/main.tf index 8760d445f0c..90a02addd80 100644 --- a/terraform/litellm/gcp/examples/default/main.tf +++ b/terraform/litellm/gcp/examples/default/main.tf @@ -38,6 +38,8 @@ module "litellm" { image_registry = var.image_registry image_tag = var.image_tag + invoker_iam_disabled = var.invoker_iam_disabled + lb_domains = var.lb_domains allow_plaintext_lb = var.allow_plaintext_lb cloudsql_deletion_protection = var.cloudsql_deletion_protection diff --git a/terraform/litellm/gcp/examples/default/variables.tf b/terraform/litellm/gcp/examples/default/variables.tf index 56e5ec88ef8..9b4d975f15c 100644 --- a/terraform/litellm/gcp/examples/default/variables.tf +++ b/terraform/litellm/gcp/examples/default/variables.tf @@ -64,6 +64,13 @@ variable "image_tag" { default = "v1.86.0-dev" } +# ---------- Load balancer auth mechanism ---------- +variable "invoker_iam_disabled" { + description = "Disable the Cloud Run invoker IAM check. When true, the allUsers grant is skipped. Enable if the environment implements the DomainRestrictedSharing policy." + type = bool + default = null +} + # TLS — provide DNS names for a managed cert, or opt into HTTP-only for dev. variable "lb_domains" { description = "DNS names (already pointing at lb_ip) for a Google-managed cert. Empty → no TLS." diff --git a/terraform/litellm/gcp/migrations.tf b/terraform/litellm/gcp/migrations.tf new file mode 100644 index 00000000000..2ec82716a6c --- /dev/null +++ b/terraform/litellm/gcp/migrations.tf @@ -0,0 +1,14 @@ +moved { + from = google_cloud_run_v2_service_iam_member.gateway_allusers + to = google_cloud_run_v2_service_iam_member.gateway_allusers[0] +} + +moved { + from = google_cloud_run_v2_service_iam_member.backend_allusers + to = google_cloud_run_v2_service_iam_member.backend_allusers[0] +} + +moved { + from = google_cloud_run_v2_service_iam_member.ui_allusers + to = google_cloud_run_v2_service_iam_member.ui_allusers[0] +} diff --git a/terraform/litellm/gcp/variables.tf b/terraform/litellm/gcp/variables.tf index 1162e100bb2..7305795e949 100644 --- a/terraform/litellm/gcp/variables.tf +++ b/terraform/litellm/gcp/variables.tf @@ -155,6 +155,13 @@ variable "migrations_image" { default = "" } +# ---------- Load balancer auth mechanism ---------- +variable "invoker_iam_disabled" { + description = "Disable the Cloud Run invoker IAM check. When true, the allUsers grant is skipped. Enable if the environment implements the DomainRestrictedSharing policy." + type = bool + default = null +} + # ---------- Service sizing ---------- variable "gateway_cpu" {