diff --git a/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf b/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf index 7fbe780c..6fc1948e 100644 --- a/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf +++ b/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf @@ -79,19 +79,18 @@ module "cf" { name = var.name bucket_name = "${var.name}-${random_pet.random.id}" bucket_config = { - location = var.region - lifecycle_delete_age = null + location = var.region } bundle_config = { source_dir = "cf" output_path = var.bundle_path - excludes = null } service_account = module.service-account.email trigger_config = { - event = "google.pubsub.topic.publish" - resource = module.pubsub.topic.id - retry = null + v1 = { + event = "google.pubsub.topic.publish" + resource = module.pubsub.topic.id + } } } diff --git a/blueprints/cloud-operations/network-dashboard/main.tf b/blueprints/cloud-operations/network-dashboard/main.tf index 5710f25c..5dd62761 100644 --- a/blueprints/cloud-operations/network-dashboard/main.tf +++ b/blueprints/cloud-operations/network-dashboard/main.tf @@ -137,15 +137,13 @@ module "cloud-function" { name = "network-dashboard-cloud-function" bucket_name = "${local.monitoring_project}-network-dashboard-bucket" bucket_config = { - location = var.region - lifecycle_delete_age = null + location = var.region } region = var.region bundle_config = { source_dir = "cloud-function" output_path = "cloud-function.zip" - excludes = null } function_config = { @@ -169,10 +167,17 @@ module "cloud-function" { # Internal only doesn't seem to work with CFv2: ingress_settings = var.cf_version == "V2" ? "ALLOW_ALL" : "ALLOW_INTERNAL_ONLY" - trigger_config = { - event = "google.pubsub.topic.publish" - resource = module.pubsub.topic.id - retry = null + trigger_config = var.cf_version == "V2" ? { + v2 = { + event_type = "google.cloud.pubsub.topic.v1.messagePublished" + pubsub_topic = module.pubsub.topic.id + # TODO: service_account_email + } + } : { + v1 = { + event = "google.pubsub.topic.publish" + resource = module.pubsub.topic.id + } } } diff --git a/blueprints/cloud-operations/quota-monitoring/main.tf b/blueprints/cloud-operations/quota-monitoring/main.tf index 13804ba9..fae9af51 100644 --- a/blueprints/cloud-operations/quota-monitoring/main.tf +++ b/blueprints/cloud-operations/quota-monitoring/main.tf @@ -52,13 +52,11 @@ module "cf" { name = var.name bucket_name = "${var.name}-${random_pet.random.id}" bucket_config = { - location = var.region - lifecycle_delete_age = null + location = var.region } bundle_config = { source_dir = "cf" output_path = var.bundle_path - excludes = null } # https://github.com/hashicorp/terraform-provider-archive/issues/40 # https://issuetracker.google.com/issues/155215191 @@ -68,9 +66,10 @@ module "cf" { } service_account_create = true trigger_config = { - event = "google.pubsub.topic.publish" - resource = module.pubsub.topic.id - retry = null + v1 = { + event = "google.pubsub.topic.publish" + resource = module.pubsub.topic.id + } } } diff --git a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf index 15d479a3..43665405 100644 --- a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf +++ b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf @@ -91,19 +91,18 @@ module "cf" { name = var.name bucket_name = "${var.name}-${random_pet.random.id}" bucket_config = { - location = var.region - lifecycle_delete_age = null + location = var.region } bundle_config = { source_dir = "cf" output_path = var.bundle_path - excludes = null } service_account = module.service-account.email trigger_config = { - event = "google.pubsub.topic.publish" - resource = module.pubsub.topic.id - retry = null + v1 = { + event = "google.pubsub.topic.publish" + resource = module.pubsub.topic.id + } } } @@ -125,9 +124,11 @@ module "cffile" { } service_account = module.service-account.email trigger_config = { - event = "google.pubsub.topic.publish" - resource = module.pubsub_file.topic.id - retry = null + v1 = { + event = "google.pubsub.topic.publish" + resource = module.pubsub_file.topic.id + retry = null + } } } diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf b/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf index 98882b05..088f8aaf 100644 --- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf +++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf @@ -114,13 +114,11 @@ module "cf-restarter" { region = var.region bucket_name = "cf-bundle-bucket-${random_pet.random.id}" bucket_config = { - location = var.region - lifecycle_delete_age = null + location = var.region } bundle_config = { source_dir = "${path.module}/function/restarter" output_path = "restarter.zip" - excludes = [] } service_account = module.service-account-restarter.email @@ -134,9 +132,10 @@ module "cf-restarter" { } trigger_config = { - event = "google.pubsub.topic.publish" - resource = module.pubsub.topic.id - retry = null + v1 = { + event = "google.pubsub.topic.publish" + resource = module.pubsub.topic.id + } } } @@ -151,7 +150,6 @@ module "cf-healthchecker" { bundle_config = { source_dir = "${path.module}/function/healthchecker" output_path = "healthchecker.zip" - excludes = [] } service_account = module.service-account-healthchecker.email diff --git a/blueprints/networking/private-cloud-function-from-onprem/main.tf b/blueprints/networking/private-cloud-function-from-onprem/main.tf index e2f23f1f..5824c319 100644 --- a/blueprints/networking/private-cloud-function-from-onprem/main.tf +++ b/blueprints/networking/private-cloud-function-from-onprem/main.tf @@ -195,11 +195,9 @@ module "function-hello" { bundle_config = { source_dir = "${path.module}/assets" output_path = "bundle.zip" - excludes = null } bucket_config = { - location = var.region - lifecycle_delete_age = null + location = var.region } iam = { "roles/cloudfunctions.invoker" = ["allUsers"] diff --git a/modules/cloud-function/README.md b/modules/cloud-function/README.md index 89faca9c..eb64cf55 100644 --- a/modules/cloud-function/README.md +++ b/modules/cloud-function/README.md @@ -50,23 +50,25 @@ Other trigger types other than HTTP are configured via the `trigger_config` vari ```hcl module "cf-http" { - source = "./fabric/modules/cloud-function" - project_id = "my-project" - name = "test-cf-http" - bucket_name = "test-cf-bundles" + source = "./fabric/modules/cloud-function" + project_id = "my-project" + 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" + v1 = { + event = "google.pubsub.topic.publish" + resource = "local.my-topic" + } } } # tftest modules=1 resources=2 ``` -Cloud Functions 2nd gen support only [Eventarc](https://cloud.google.com/eventarc/docs) and user separate structure +Cloud Functions 2nd gen support only [Eventarc](https://cloud.google.com/eventarc/docs) and uses separate structure to configure: ```hcl module "trigger-service-account" { @@ -81,19 +83,21 @@ module "trigger-service-account" { } module "cf-http" { - source = "./fabric/modules/cloud-function" - project_id = "my-project" - v2 = true - name = "test-cf-http" - bucket_name = "test-cf-bundles" + source = "./fabric/modules/cloud-function" + project_id = "my-project" + v2 = true + name = "test-cf-http" + bucket_name = "test-cf-bundles" bundle_config = { source_dir = "fabric/assets/" output_path = "bundle.zip" } - trigger_config_v2 = { - event_type = "google.cloud.pubsub.topic.v1.messagePublished" - pubsub_topic = "local.my-topic" - service_account_email = module.trigger-service-account.email + trigger_config = { + v2 = { + 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 @@ -230,20 +234,19 @@ module "cf-http" { | [build_worker_pool](variables.tf#L31) | Build worker pool, in projects//locations//workerPools/ format | string | | null | | [description](variables.tf#L46) | Optional description. | string | | "Terraform managed." | | [environment_variables](variables.tf#L52) | Cloud function environment variables. | map(string) | | {} | -| [function_config](variables.tf#L58) | Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout | object({…}) | | {…} | +| [function_config](variables.tf#L58) | Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout | object({…}) | | {…} | | [iam](variables.tf#L76) | IAM bindings for topic in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | | [ingress_settings](variables.tf#L82) | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . | string | | null | | [labels](variables.tf#L88) | Resource labels. | map(string) | | {} | | [prefix](variables.tf#L99) | Optional prefix used for resource names. | string | | null | | [region](variables.tf#L114) | Region used for all resources. | string | | "europe-west1" | | [secrets](variables.tf#L120) | Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format. | map(object({…})) | | {} | -| [service_account](variables.tf#L132) | Service account email.service_account Unused if service account is auto-created. | string | | null | +| [service_account](variables.tf#L132) | Service account email. Unused if service account is auto-created. | string | | null | | [service_account_create](variables.tf#L138) | Auto-create service account. | bool | | false | -| [trigger_config](variables.tf#L144) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | -| [trigger_config_v2](variables.tf#L154) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | -| [v2](variables.tf#L190) | Whether to use Cloud Function version 2nd Gen or 1st Gen. | bool | | false | -| [vpc_connector](variables.tf#L171) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | object({…}) | | null | -| [vpc_connector_config](variables.tf#L181) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null | +| [trigger_config](variables.tf#L144) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | +| [v2](variables.tf#L191) | Whether to use Cloud Function version 2nd Gen or 1st Gen. | bool | | false | +| [vpc_connector](variables.tf#L172) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | object({…}) | | null | +| [vpc_connector_config](variables.tf#L182) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null | ## Outputs diff --git a/modules/cloud-function/main.tf b/modules/cloud-function/main.tf index 5a080ced..816ed259 100644 --- a/modules/cloud-function/main.tf +++ b/modules/cloud-function/main.tf @@ -75,7 +75,7 @@ resource "google_cloudfunctions_function" "function" { source_archive_bucket = local.bucket source_archive_object = google_storage_bucket_object.bundle.name labels = var.labels - trigger_http = var.trigger_config == null ? true : null + trigger_http = try(var.trigger_config.v1 == null, true) ? true : null ingress_settings = var.ingress_settings build_worker_pool = var.build_worker_pool @@ -85,14 +85,14 @@ resource "google_cloudfunctions_function" "function" { ) dynamic "event_trigger" { - for_each = var.trigger_config == null ? [] : [""] + for_each = try(var.trigger_config.v1 == null, true) ? [] : [""] content { - event_type = var.trigger_config.event - resource = var.trigger_config.resource + event_type = var.trigger_config.v1.event + resource = var.trigger_config.v1.resource dynamic "failure_policy" { - for_each = var.trigger_config.retry == null ? [] : [""] + for_each = var.trigger_config.v1.retry == null ? [] : [""] content { - retry = var.trigger_config.retry + retry = var.trigger_config.v1.retry } } } @@ -148,13 +148,13 @@ resource "google_cloudfunctions2_function" "function" { } } dynamic "event_trigger" { - for_each = var.trigger_config_v2 == null ? [] : [""] + for_each = try(var.trigger_config.v2 == null, true) ? [] : [""] content { - trigger_region = var.trigger_config_v2.region - event_type = var.trigger_config_v2.event_type - pubsub_topic = var.trigger_config_v2.pubsub_topic + trigger_region = var.trigger_config.v2.region + event_type = var.trigger_config.v2.event_type + pubsub_topic = var.trigger_config.v2.pubsub_topic dynamic "event_filters" { - for_each = var.trigger_config_v2.event_filters + for_each = var.trigger_config.v2.event_filters == null ? [] : var.trigger_config.v2.event_filters iterator = event_filter content { attribute = event_filter.attribute @@ -162,8 +162,8 @@ resource "google_cloudfunctions2_function" "function" { operator = event_filter.operator } } - service_account_email = var.trigger_config_v2.service_account_email - retry_policy = var.trigger_config_v2.retry_policy + service_account_email = var.trigger_config.v2.service_account_email + retry_policy = var.trigger_config.v2.retry_policy } } service_config { diff --git a/modules/cloud-function/variables.tf b/modules/cloud-function/variables.tf index d7fa6a22..93d3634a 100644 --- a/modules/cloud-function/variables.tf +++ b/modules/cloud-function/variables.tf @@ -61,7 +61,7 @@ variable "function_config" { entry_point = optional(string, "main") instances = optional(number, 1) memory = optional(number, 256) # Memory in MB - runtime = optional(string, "python37") + runtime = optional(string, "python310") timeout = optional(number, 180) }) default = { @@ -130,7 +130,7 @@ variable "secrets" { } variable "service_account" { - description = "Service account email.service_account Unused if service account is auto-created." + description = "Service account email. Unused if service account is auto-created." type = string default = null } @@ -144,28 +144,29 @@ variable "service_account_create" { variable "trigger_config" { description = "Function trigger configuration. Leave null for HTTP trigger." type = object({ - event = string - resource = string - retry = optional(bool) - }) - default = null -} - -variable "trigger_config_v2" { - description = "Function trigger configuration. Leave null for HTTP trigger." - type = object({ - region = optional(string) - event_type = optional(string) - pubsub_topic = optional(string) - event_filters = optional(list(object({ - attribute = string - value = string - operator = string - })), []) - service_account_email = optional(string) - retry_policy = optional(string) + v1 = optional(object({ + event = string + resource = string + retry = optional(bool) + })), + v2 = optional(object({ + region = optional(string) + event_type = optional(string) + pubsub_topic = optional(string) + event_filters = optional(list(object({ + attribute = string + value = string + operator = string + }))) + service_account_email = optional(string) + retry_policy = optional(string) + })) }) default = null + validation { + condition = try(((var.trigger_config.v1 == null) != (var.trigger_config.v2 == null)), var.trigger_config == null) + error_message = "Provide configuration for only one generation - either v1 or v2" + } } variable "vpc_connector" {