IaC Bazaar
Google CloudPlan-validated

Cloud Run Function (gen2)

Event-driven or HTTP gen2 function with source upload, dedicated runtime SA and Eventarc trigger wiring.

terraformGCP#gcp

Compare Serverless Functions across clouds →

gcp-cloud-functionterraform v1.7

Verification

Plan-validated

Passed: module logic verified on a mocked plan — inputs, validation rules, conditional creation and outputs resolve (no real provider, no cloud).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan: findings disclosed (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-06-28 · how we verify

Documentation

gcp-cloud-function

A Cloud Run function (gen2) — HTTP or event-driven — with the source zip uploaded to GCS, a dedicated runtime service account, least-privilege Secret Manager grants wired automatically, optional Eventarc trigger, VPC egress, and private invoker IAM. One module call gives you a production function whose identity is not the default compute service account and whose HTTP surface is locked down unless you explicitly open it. Works with Terraform and OpenTofu (>= 1.6), Google provider >= 7.0, < 8.0.

Status: static-validated, live-test pending. Validated with tofu validate + tflint + checkov against the hashicorp/google provider. Not yet applied against a live GCP project (no cloud sandbox), so it ships under live-test quarantine.

Design & secure defaults

  • Dedicated runtime service account (<name>-fn) — never the default compute SA. Supply your own with create_service_account = false.
  • Private by default: no invoker IAM unless you list invoker_members; allUsers only via the explicit allow_unauthenticated = true opt-in.
  • Least-privilege secrets: roles/secretmanager.secretAccessor is granted per referenced secret, not project-wide. Cross-project secrets are left for you to grant where they live.
  • Content-addressed source: the uploaded object name defaults to <name>/<md5>.zip, so a changed zip forces a fresh build.
  • Cost cap: max_instance_count = 10 by default; gen2 request concurrency starts at 1 (raise deliberately).
  • VPC egress via a Serverless VPC Access connector, PRIVATE_RANGES_ONLY by default.

Usage

module "http_function" {
  source = "./gcp-cloud-function"

  project_id  = "my-project"
  name        = "checkout-fn"
  location    = "us-central1"
  runtime     = "nodejs22"
  entry_point = "handler"

  source_bucket   = "my-project-fn-source" # private, uniform-access bucket
  source_zip_path = "${path.module}/build/checkout.zip"

  environment_variables        = { LOG_LEVEL = "info" }
  secret_environment_variables = { DATABASE_URL = { secret = "checkout-db-url" } }

  invoker_members = ["serviceAccount:[email protected]"]
  labels          = { environment = "prod" }
}

Event-driven (Pub/Sub) function — omit invoker_members, supply event_trigger:

event_trigger = {
  event_type   = "google.cloud.pubsub.topic.v1.messagePublished"
  pubsub_topic = "projects/my-project/topics/orders"
  retry_policy = "RETRY_POLICY_RETRY"
}

For Cloud Storage triggers, use event_type = "google.cloud.storage.object.v1.finalized" and event_filters = { bucket = "my-bucket" }.

When event_trigger is set the module grants the runtime SA roles/eventarc.eventReceiver + roles/run.invoker before the function (and, for google.cloud.storage.* events, roles/pubsub.publisher to the Cloud Storage service agent) so Eventarc accepts the trigger and the event-driven path applies in a single apply.

Requirements

RequirementVersion
Terraform / OpenTofu>= 1.6
hashicorp/google>= 7.0, < 8.0

Inputs

NameTypeDefaultDescription
project_idstringGCP project ID (required)
namestringFunction name (required)
locationstringRegion (required)
runtimestringLanguage runtime e.g. nodejs22 (required)
entry_pointstringExported function/method to run (required)
source_bucketstringGCS bucket for the source zip (required)
source_zip_pathstringLocal path to the source zip (required)
source_object_namestringnullObject name (defaults to content-addressed)
descriptionstringnullFunction description
available_memorystring"256Mi"Memory per instance
available_cpustringnullCPU per instance (null = derived)
timeout_secondsnumber60Request timeout (1–3600)
min_instance_countnumber0Warm instances (0 = scale to zero)
max_instance_countnumber10Max instances (cost cap)
max_instance_request_concurrencynumber1Concurrent requests per instance
environment_variablesmap(string){}Plain runtime env vars
build_environment_variablesmap(string){}Build-time env vars
secret_environment_variablesmap(object){}Env vars from Secret Manager (secret, version, project_id)
ingress_settingsstringALLOW_ALLIngress restriction
all_traffic_on_latest_revisionbooltrueRoute all traffic to latest revision
vpc_connectorstringnullServerless VPC Access connector
vpc_connector_egress_settingsstringPRIVATE_RANGES_ONLYVPC egress mode
create_service_accountbooltrueCreate dedicated runtime SA
service_account_emailstringnullExisting runtime SA (when not creating one)
grant_secret_accessbooltrueAuto-grant secretAccessor on referenced secrets
event_triggerobjectnullEventarc trigger (null = HTTP function)
allow_unauthenticatedboolfalseGrant allUsers invoker
invoker_memberslist(string)[]Members granted roles/run.invoker
labelsmap(string){}Function labels

Outputs

NameDescription
function_idFully-qualified function ID
function_nameFunction name
function_uriHTTPS URL of the underlying Cloud Run service
service_account_emailRuntime SA email
source_objectGCS bucket + object of the uploaded build source
stateLifecycle state (e.g. ACTIVE)

License

Commercial — LicenseRef-IaCBazaar-Commercial. See the IaC Bazaar terms.