From 22d27b4f68b656f1fb6c1ada20c54602bff1218a 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, 69 insertions(+), 18 deletions(-) create mode 100644 terraform/litellm/gcp/migrations.tf diff --git a/terraform/litellm/gcp/README.md b/terraform/litellm/gcp/README.md index 4b2f576adc1..288fbd79649 100644 --- a/terraform/litellm/gcp/README.md +++ b/terraform/litellm/gcp/README.md @@ -409,6 +409,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 @@ -465,6 +466,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 d0b32a367d6..781e5fb20de 100644 --- a/terraform/litellm/gcp/cloudrun.tf +++ b/terraform/litellm/gcp/cloudrun.tf @@ -225,11 +225,12 @@ locals { resource "google_cloud_run_v2_service" "gateway" { count = var.create_runtime ? 1 : 0 - 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 lifecycle { precondition { @@ -498,11 +499,12 @@ resource "google_cloud_run_v2_service" "gateway" { resource "google_cloud_run_v2_service" "backend" { count = var.create_runtime ? 1 : 0 - 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 @@ -619,11 +621,12 @@ resource "google_cloud_run_v2_service" "backend" { resource "google_cloud_run_v2_service" "ui" { count = var.create_runtime ? 1 : 0 - 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[0].email @@ -667,7 +670,7 @@ 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.create_runtime ? 1 : 0 + count = var.create_runtime && var.invoker_iam_disabled != true ? 1 : 0 project = var.project_id location = google_cloud_run_v2_service.gateway[0].location @@ -677,7 +680,7 @@ resource "google_cloud_run_v2_service_iam_member" "gateway_allusers" { } resource "google_cloud_run_v2_service_iam_member" "backend_allusers" { - count = var.create_runtime ? 1 : 0 + count = var.create_runtime && var.invoker_iam_disabled != true ? 1 : 0 project = var.project_id location = google_cloud_run_v2_service.backend[0].location @@ -687,7 +690,7 @@ resource "google_cloud_run_v2_service_iam_member" "backend_allusers" { } resource "google_cloud_run_v2_service_iam_member" "ui_allusers" { - count = var.create_runtime ? 1 : 0 + count = var.create_runtime && var.invoker_iam_disabled != true ? 1 : 0 project = var.project_id location = google_cloud_run_v2_service.ui[0].location diff --git a/terraform/litellm/gcp/examples/default/main.tf b/terraform/litellm/gcp/examples/default/main.tf index 782d4ee4b65..dc2f581b1f6 100644 --- a/terraform/litellm/gcp/examples/default/main.tf +++ b/terraform/litellm/gcp/examples/default/main.tf @@ -43,6 +43,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 08b78346df3..4cc2de4c29c 100644 --- a/terraform/litellm/gcp/examples/default/variables.tf +++ b/terraform/litellm/gcp/examples/default/variables.tf @@ -88,6 +88,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 412f919ab89..fad703fb155 100644 --- a/terraform/litellm/gcp/variables.tf +++ b/terraform/litellm/gcp/variables.tf @@ -181,6 +181,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" {