cloud-foundation-fabric/modules/cloud-function-v2
Ludovico Magnocavallo 6941313c7d
Factories refactor (#1843)
* factories refactor doc

* Adds file schema and filesystem organization

* Update 20231106-factories.md

* move factories out of blueprints and create new factories  README

* align factory in billing-account module

* align factory in dataplex-datascan module

* align factory in billing-account module

* align factory in net-firewall-policy module

* align factory in dns-response-policy module

* align factory in net-vpc-firewall module

* align factory in net-vpc module

* align factory variable names in FAST

* remove decentralized firewall blueprint

* bump terraform version

* bump module versions

* update top-level READMEs

* move project factory to modules

* fix variable names and tests

* tfdoc

* remove changelog link

* add project factory to top-level README

* fix cludrun eventarc diff

* fix README

* fix cludrun eventarc diff

---------

Co-authored-by: Simone Ruffilli <sruffilli@google.com>
2024-02-26 10:16:52 +00:00
..
README.md Remove default region for Cloud Function and Cloud Run (#2004) 2024-01-24 10:23:40 +00:00
main.tf Specify `docker_repository` field for google_cloudfunctions2_function (#1987) 2024-01-20 09:40:26 +00:00
outputs.tf use cloud run bindings for cf v2 invoker role, refactor iam handling in cf v2 and cloud run (#1609) 2023-08-22 07:23:49 +00:00
variables.tf Remove default region for Cloud Function and Cloud Run (#2004) 2024-01-24 10:23:40 +00:00
versions.tf Factories refactor (#1843) 2024-02-26 10:16:52 +00:00

README.md

Cloud Function Module (v2)

Cloud Function management, with support for IAM roles and optional bucket creation.

The GCS object used for deployment uses a hash of the bundle zip contents in its name, which ensures change tracking and avoids recreating the function if the GCS object is deleted and needs recreating.

TODO

  • add support for source_repository

Examples

HTTP trigger

This deploys a Cloud Function with an HTTP endpoint, using a pre-existing GCS bucket for deployment, setting the service account to the Cloud Function default one, and delegating access control to the containing project.

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
}
# tftest modules=1 resources=2

PubSub and non-HTTP triggers

Other trigger types other than HTTP are configured via the trigger_config variable. This example shows a PubSub trigger via Eventarc:

module "trigger-service-account" {
  source     = "./fabric/modules/iam-service-account"
  project_id = "my-project"
  name       = "sa-cloudfunction"
  iam_project_roles = {
    "my-project" = [
      "roles/run.invoker"
    ]
  }
}

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
  trigger_config = {
    event_type            = "google.cloud.pubsub.topic.v1.messagePublished"
    pubsub_topic          = "local.my-topic"
    service_account_email = module.trigger-service-account.email
  }
}
# tftest modules=2 resources=4

Ensure that pubsub service identity (service-[project number]@gcp-sa-pubsub.iam.gserviceaccount.com has roles/iam.serviceAccountTokenCreator as documented here.

Controlling HTTP access

To allow anonymous access to the function, grant the roles/run.invoker role to the special allUsers identifier. Use specific identities (service accounts, groups, etc.) instead of allUsers to only allow selective access. The Cloud Run role needs to be used as explained in the gcloud documentation.

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
  iam = {
    "roles/run.invoker" = ["allUsers"]
  }
}
# tftest modules=1 resources=3 inventory=iam.yaml

GCS bucket creation

You can have the module auto-create the GCS bucket used for deployment via the bucket_config variable. Setting bucket_config.location to null will also use the function region for GCS.

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  prefix      = "my-prefix"
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bucket_config = {
    lifecycle_delete_age_days = 1
  }
  bundle_config = {
    source_dir = "fabric/assets/"
  }
}
# tftest modules=1 resources=3 inventory=bucket-creation.yaml

Service account management

To use a custom service account managed by the module, set service_account_create to true and leave service_account set to null value (default).

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
  service_account_create = true
}
# tftest modules=1 resources=3

To use an externally managed service account, pass its email in service_account and leave service_account_create to false (the default).

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
  service_account = "non-existent@serice.account.email"
}
# tftest modules=1 resources=2

Custom bundle config

In order to help prevent archive_zip.output_md5 from changing cross platform (e.g. Cloud Build vs your local development environment), you'll have to make sure that the files included in the zip are always the same.

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets"
    output_path = "bundle.zip"
    excludes    = ["__pycache__"]
  }
}
# tftest modules=1 resources=2

Private Cloud Build Pool

This deploys a Cloud Function with an HTTP endpoint, using a pre-existing GCS bucket for deployment using a pre existing private Cloud Build worker pool.

module "cf-http" {
  source            = "./fabric/modules/cloud-function-v2"
  project_id        = "my-project"
  region            = var.region
  name              = "test-cf-http"
  bucket_name       = "test-cf-bundles"
  build_worker_pool = "projects/my-project/locations/europe-west1/workerPools/my_build_worker_pool"
  bundle_config = {
    source_dir  = "fabric/assets"
    output_path = "bundle.zip"
  }
}
# tftest modules=1 resources=2

Multiple Cloud Functions within project

When deploying multiple functions do not reuse bundle_config.output_path between instances as the result is undefined. Default output_path creates file in /tmp folder using project Id and function name to avoid name conflicts.

module "cf-http-one" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http-one"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir = "fabric/assets"
  }
}

module "cf-http-two" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http-two"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir = "fabric/assets"
  }
}
# tftest modules=2 resources=4 inventory=multiple_functions.yaml

Mounting secrets from Secret Manager

This provides the latest value of the secret var_secret as VARIABLE_SECRET environment variable and three values of path_secret mounted in filesystem:

  • /app/secret/first contains version 1
  • /app/secret/second contains version 2
  • /app/secret/latest contains latest version of the secret
module "cf-http" {
  source      = "./fabric/modules/cloud-function-v2"
  project_id  = "my-project"
  region      = var.region
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets"
    output_path = "bundle.zip"
  }
  secrets = {
    VARIABLE_SECRET = {
      is_volume  = false
      project_id = 1234567890
      secret     = "var_secret"
      versions = [
        "latest"
      ]
    }
    "/app/secret" = {
      is_volume  = true
      project_id = 1234567890
      secret     = "path_secret"
      versions = [
        "1:first",
        "2:second",
        "latest:latest"
      ]
    }
  }
}

# tftest modules=1 resources=2 inventory=secrets.yaml

Variables

name description type required default
bucket_name Name of the bucket that will be used for the function code. It will be created with prefix prepended if bucket_config is not null. string
bundle_config Cloud function source folder and generated zip bundle paths. Output path defaults to '/tmp/bundle.zip' if null. object({…})
name Name used for cloud function and associated resources. string
project_id Project id used for all resources. string
region Region used for all resources. string
bucket_config Enable and configure auto-created bucket. Set fields to null to use defaults. object({…}) null
build_worker_pool Build worker pool, in projects//locations//workerPools/<POOL_NAME> format. string null
description Optional description. string "Terraform managed."
docker_repository_id User managed repository created in Artifact Registry. string null
environment_variables Cloud function environment variables. map(string) {}
function_config Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout. object({…}) {…}
iam IAM bindings for topic in {ROLE => [MEMBERS]} format. map(list(string)) {}
ingress_settings Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . string null
labels Resource labels. map(string) {}
prefix Optional prefix used for resource names. string null
secrets Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format. map(object({…})) {}
service_account Service account email. Unused if service account is auto-created. string null
service_account_create Auto-create service account. bool false
trigger_config Function trigger configuration. Leave null for HTTP trigger. object({…}) null
vpc_connector VPC connector configuration. Set create to 'true' if a new connector needs to be created. object({…}) null
vpc_connector_config VPC connector network configuration. Must be provided if new VPC connector is being created. object({…}) null

Outputs

name description sensitive
bucket Bucket resource (only if auto-created).
bucket_name Bucket name.
function Cloud function resources.
function_name Cloud function name.
id Fully qualified function id.
service_account Service account resource.
service_account_email Service account email.
service_account_iam_email Service account email.
trigger_service_account Service account resource.
trigger_service_account_email Service account email.
trigger_service_account_iam_email Service account email.
uri Cloud function service uri.
vpc_connector VPC connector resource if created.