Skip to content

Latest commit

 

History

History
327 lines (288 loc) · 15.3 KB

File metadata and controls

327 lines (288 loc) · 15.3 KB

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 = "[email protected]"
}
# 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

Using CMEK to encrypt function resources

This encrypt bucket gcf-sources-* with the provided kms key. The repository has to be encrypted with the same kms key.

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"
  }
  kms_key = "projects/my-project/locations/europe-west1/keyRings/mykeyring/cryptoKeys/mykey"
  repository_settings = {
    repository = "projects/my-project/locations/europe-west1/repositories/myrepo"
  }
}
# tftest modules=1 resources=2

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_environment_variables A set of key/value environment variable pairs available during build time. map(string) {}
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
kms_key Resource name of a KMS crypto key (managed by the user) used to encrypt/decrypt function resources in key id format. If specified, you must also provide an artifact registry repository using the docker_repository field that was created with the same KMS crypto key. string null
labels Resource labels. map(string) {}
prefix Optional prefix used for resource names. string null
repository_settings Docker Registry to use for storing the function's Docker images and specific repository. If kms_key is provided, the repository must have already been encrypted with the key. object({…}) {…}
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.