cloud-foundation-fabric/modules/cloud-function-v1
Mohamed Ikbal Belbahri ae6ee03de2
Add https security to cloud-functions-v1 module (#2118)
* Add https security level to cf v1 module
* Update tfdoc.py raw strings for slug var to avoid [SyntaxWarning: invalid escape sequence]
2024-02-28 21:20:56 +01:00
..
README.md Add https security to cloud-functions-v1 module (#2118) 2024-02-28 21:20:56 +01:00
main.tf Add https security to cloud-functions-v1 module (#2118) 2024-02-28 21:20:56 +01:00
outputs.tf Split Cloud Function module in separate v1 and v2 modules (#1450) 2023-06-19 12:50:36 +02:00
variables.tf Add https security to cloud-functions-v1 module (#2118) 2024-02-28 21:20:56 +01:00
versions.tf Factories refactor (#1843) 2024-02-26 10:16:52 +00:00

README.md

Cloud Function Module (V1)

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-v1"
  project_id  = var.project_id
  region      = "europe-west1"
  name        = "test-cf-http"
  bucket_name = var.bucket
  bundle_config = {
    source_dir  = "assets/sample-function/"
    output_path = "bundle.zip"
  }
}
# tftest modules=1 resources=2 e2e

PubSub and non-HTTP triggers

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

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
  trigger_config = {
    event    = "google.pubsub.topic.publish"
    resource = "local.my-topic"
  }
}
# tftest modules=1 resources=2

Controlling HTTP access

To allow anonymous access to the function, grant the roles/cloudfunctions.invoker role to the special allUsers identifier. Use specific identities (service accounts, groups, etc.) instead of allUsers to only allow selective access.

module "cf-http" {
  source      = "./fabric/modules/cloud-function-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  name        = "test-cf-http"
  bucket_name = "test-cf-bundles"
  bundle_config = {
    source_dir  = "fabric/assets/"
    output_path = "bundle.zip"
  }
  iam = {
    "roles/cloudfunctions.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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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-v1"
  project_id        = "my-project"
  region            = "europe-west1"
  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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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-v1"
  project_id  = "my-project"
  region      = "europe-west1"
  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."
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({…}) {…}
https_security_level The security level for the function: Allowed values are SECURE_ALWAYS, SECURE_OPTIONAL. string null
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.
vpc_connector VPC connector resource if created.