From 1da5bde47b5364b383e05153ab1ced95b3c291c6 Mon Sep 17 00:00:00 2001 From: Andras Gyomrey Date: Sat, 6 Nov 2021 13:48:22 +0000 Subject: [PATCH] Support for consistent function bundles --- .../asset-inventory-feed-remediation/main.tf | 6 +- cloud-operations/quota-monitoring/main.tf | 6 +- .../main.tf | 6 +- modules/cloud-function/README.md | 58 ++++++++++++++----- modules/cloud-function/main.tf | 2 + modules/cloud-function/variables.tf | 6 +- .../main.tf | 6 +- tests/modules/cloud_function/fixture/main.tf | 6 +- 8 files changed, 71 insertions(+), 25 deletions(-) diff --git a/cloud-operations/asset-inventory-feed-remediation/main.tf b/cloud-operations/asset-inventory-feed-remediation/main.tf index 413b25b9f..7cfbbca0b 100644 --- a/cloud-operations/asset-inventory-feed-remediation/main.tf +++ b/cloud-operations/asset-inventory-feed-remediation/main.tf @@ -88,8 +88,10 @@ module "cf" { lifecycle_delete_age = null } bundle_config = { - source_dir = "cf" - output_path = var.bundle_path + source_dir = "cf" + output_path = var.bundle_path + output_file_mode = null + excludes = null } service_account = module.service-account.email trigger_config = { diff --git a/cloud-operations/quota-monitoring/main.tf b/cloud-operations/quota-monitoring/main.tf index 503dbf3c0..53022a978 100644 --- a/cloud-operations/quota-monitoring/main.tf +++ b/cloud-operations/quota-monitoring/main.tf @@ -60,8 +60,10 @@ module "cf" { lifecycle_delete_age = null } bundle_config = { - source_dir = "cf" - output_path = var.bundle_path + source_dir = "cf" + output_path = var.bundle_path + output_file_mode = null + excludes = null } # https://github.com/hashicorp/terraform-provider-archive/issues/40 # https://issuetracker.google.com/issues/155215191 diff --git a/cloud-operations/scheduled-asset-inventory-export-bq/main.tf b/cloud-operations/scheduled-asset-inventory-export-bq/main.tf index 005c0fe38..abce7babc 100644 --- a/cloud-operations/scheduled-asset-inventory-export-bq/main.tf +++ b/cloud-operations/scheduled-asset-inventory-export-bq/main.tf @@ -80,8 +80,10 @@ module "cf" { lifecycle_delete_age = null } bundle_config = { - source_dir = "cf" - output_path = var.bundle_path + source_dir = "cf" + output_path = var.bundle_path + output_file_mode = null + excludes = null } service_account = module.service-account.email trigger_config = { diff --git a/modules/cloud-function/README.md b/modules/cloud-function/README.md index 935c58aeb..724e05029 100644 --- a/modules/cloud-function/README.md +++ b/modules/cloud-function/README.md @@ -21,8 +21,10 @@ module "cf-http" { name = "test-cf-http" bucket_name = "test-cf-bundles" bundle_config = { - source_dir = "my-cf-source-folder" - output_path = "bundle.zip" + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } } # tftest:skip @@ -39,8 +41,10 @@ module "cf-http" { name = "test-cf-http" bucket_name = "test-cf-bundles" bundle_config = { - source_dir = "my-cf-source-folder" - output_path = "bundle.zip" + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } trigger_config = { event = "google.pubsub.topic.publish" @@ -62,8 +66,10 @@ module "cf-http" { name = "test-cf-http" bucket_name = "test-cf-bundles" bundle_config = { - source_dir = "my-cf-source-folder" - output_path = "bundle.zip" + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } iam = { "roles/cloudfunctions.invoker" = ["allUsers"] @@ -87,8 +93,10 @@ module "cf-http" { lifecycle_delete_age = 1 } bundle_config = { - source_dir = "my-cf-source-folder" - output_path = "bundle.zip" + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } } # tftest:skip @@ -105,8 +113,10 @@ module "cf-http" { name = "test-cf-http" bucket_name = "test-cf-bundles" bundle_config = { - source_dir = "my-cf-source-folder" - output_path = "bundle.zip" + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } service_account_create = true } @@ -122,21 +132,43 @@ module "cf-http" { name = "test-cf-http" bucket_name = "test-cf-bundles" bundle_config = { - source_dir = "my-cf-source-folder" - output_path = "bundle.zip" + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } service_account = local.service_account_email } # tftest:skip ``` +### 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. On top of this, Terraform recommends to additionally (set the octal file mode to "0666")[https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/archive_file#output_file_mode] to ensure that the modes of the archived files don't vary either. + +```hcl +module "cf-http" { + source = "./modules/cloud-function" + project_id = "my-project" + name = "test-cf-http" + bucket_name = "test-cf-bundles" + bundle_config = { + source_dir = "my-cf-source-folder" + output_path = "bundle.zip" + output_file_mode = "0666" + excludes = ["__pycache__"] + } +} +# tftest:skip +``` + ## 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({...}) | ✓ | | +| 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 | ✓ | | | *bucket_config* | Enable and configure auto-created bucket. Set fields to null to use defaults. | object({...}) | | null | diff --git a/modules/cloud-function/main.tf b/modules/cloud-function/main.tf index de04f2288..5223155b6 100644 --- a/modules/cloud-function/main.tf +++ b/modules/cloud-function/main.tf @@ -137,6 +137,8 @@ data "archive_file" "bundle" { ? "/tmp/bundle.zip" : var.bundle_config.output_path ) + output_file_mode = var.bundle_config.output_file_mode + excludes = var.bundle_config.excludes } resource "google_service_account" "service_account" { diff --git a/modules/cloud-function/variables.tf b/modules/cloud-function/variables.tf index 05c57e36f..3632ca069 100644 --- a/modules/cloud-function/variables.tf +++ b/modules/cloud-function/variables.tf @@ -31,8 +31,10 @@ variable "bucket_name" { variable "bundle_config" { description = "Cloud function source folder and generated zip bundle paths. Output path defaults to '/tmp/bundle.zip' if null." type = object({ - source_dir = string - output_path = string + source_dir = string + output_path = string + output_file_mode = string + excludes = list(string) }) } diff --git a/networking/private-cloud-function-from-onprem/main.tf b/networking/private-cloud-function-from-onprem/main.tf index a51fa363a..362cafa14 100644 --- a/networking/private-cloud-function-from-onprem/main.tf +++ b/networking/private-cloud-function-from-onprem/main.tf @@ -206,8 +206,10 @@ module "function-hello" { bucket_name = "${var.name}-tf-cf-deploy" ingress_settings = "ALLOW_INTERNAL_ONLY" bundle_config = { - source_dir = "${path.module}/assets" - output_path = "bundle.zip" + source_dir = "${path.module}/assets" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } bucket_config = { location = var.region diff --git a/tests/modules/cloud_function/fixture/main.tf b/tests/modules/cloud_function/fixture/main.tf index d624c2f10..a89a85e3c 100644 --- a/tests/modules/cloud_function/fixture/main.tf +++ b/tests/modules/cloud_function/fixture/main.tf @@ -20,8 +20,10 @@ module "test" { name = "test" bucket_name = var.bucket_name bundle_config = { - source_dir = "bundle" - output_path = "bundle.zip" + source_dir = "bundle" + output_path = "bundle.zip" + output_file_mode = null + excludes = null } iam = { "roles/cloudfunctions.invoker" = ["allUsers"]