diff --git a/blueprints/apigee/apigee-x-foundations/monitoring.tf b/blueprints/apigee/apigee-x-foundations/monitoring.tf
index 70d3a2195d..5e633f9798 100644
--- a/blueprints/apigee/apigee-x-foundations/monitoring.tf
+++ b/blueprints/apigee/apigee-x-foundations/monitoring.tf
@@ -23,7 +23,7 @@ module "instance_monitor_function" {
bucket_config = {
}
bundle_config = {
- source_dir = "${path.module}/functions/instance-monitor"
+ path = "${path.module}/functions/instance-monitor"
output_path = "bundle.zip"
}
function_config = {
diff --git a/blueprints/apigee/bigquery-analytics/main.tf b/blueprints/apigee/bigquery-analytics/main.tf
index 5e8404283e..f2c31f2108 100644
--- a/blueprints/apigee/bigquery-analytics/main.tf
+++ b/blueprints/apigee/bigquery-analytics/main.tf
@@ -164,7 +164,7 @@ module "function_export" {
lifecycle_delete_age = 1
}
bundle_config = {
- source_dir = "${path.module}/functions/export"
+ path = "${path.module}/functions/export"
output_path = "${path.module}/bundle-export.zip"
excludes = null
}
@@ -200,7 +200,7 @@ module "function_gcs2bq" {
lifecycle_delete_age = 1
}
bundle_config = {
- source_dir = "${path.module}/functions/gcs2bq"
+ path = "${path.module}/functions/gcs2bq"
output_path = "${path.module}/bundle-gcs2bq.zip"
excludes = null
}
diff --git a/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf b/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf
index 18ae142575..c84f526e30 100644
--- a/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf
+++ b/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf
@@ -85,7 +85,7 @@ module "cf" {
location = var.region
}
bundle_config = {
- source_dir = "${path.module}/cf"
+ path = "${path.module}/cf"
output_path = var.bundle_path
}
service_account = module.service-account.email
diff --git a/blueprints/cloud-operations/compute-quota-monitoring/main.tf b/blueprints/cloud-operations/compute-quota-monitoring/main.tf
index d5f9a48666..f81515544c 100644
--- a/blueprints/cloud-operations/compute-quota-monitoring/main.tf
+++ b/blueprints/cloud-operations/compute-quota-monitoring/main.tf
@@ -60,7 +60,7 @@ module "cf" {
location = var.region
}
bundle_config = {
- source_dir = "${path.module}/src"
+ path = "${path.module}/src"
output_path = var.bundle_path
}
service_account_create = true
diff --git a/blueprints/cloud-operations/network-quota-monitoring/deploy-cloud-function/main.tf b/blueprints/cloud-operations/network-quota-monitoring/deploy-cloud-function/main.tf
index 4ab9aa54a6..c3d8e2d5bc 100644
--- a/blueprints/cloud-operations/network-quota-monitoring/deploy-cloud-function/main.tf
+++ b/blueprints/cloud-operations/network-quota-monitoring/deploy-cloud-function/main.tf
@@ -73,7 +73,7 @@ module "cloud-function" {
}
build_worker_pool = var.cloud_function_config.build_worker_pool_id
bundle_config = {
- source_dir = var.cloud_function_config.source_dir
+ path = var.cloud_function_config.source_dir
output_path = var.cloud_function_config.bundle_path
}
environment_variables = (
@@ -145,7 +145,7 @@ module "cloud-function-v2" {
}
build_worker_pool = var.cloud_function_config.build_worker_pool_id
bundle_config = {
- source_dir = var.cloud_function_config.source_dir
+ path = var.cloud_function_config.source_dir
output_path = var.cloud_function_config.bundle_path
}
environment_variables = (
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 6460384ea7..9ee4fbf34f 100644
--- a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf
+++ b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf
@@ -94,7 +94,7 @@ module "cf" {
location = var.region
}
bundle_config = {
- source_dir = "${path.module}/cf"
+ path = "${path.module}/cf"
output_path = var.bundle_path
}
service_account = module.service-account.email
@@ -116,7 +116,7 @@ module "cffile" {
lifecycle_delete_age_days = null
}
bundle_config = {
- source_dir = "${path.module}/cffile"
+ path = "${path.module}/cffile"
output_path = var.bundle_path_cffile
excludes = null
}
diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf b/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf
index 0f1fe0190a..9cc68a839e 100644
--- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf
+++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/main.tf
@@ -117,7 +117,7 @@ module "cf-restarter" {
location = var.region
}
bundle_config = {
- source_dir = "${path.module}/function/restarter"
+ path = "${path.module}/function/restarter"
output_path = "restarter.zip"
}
service_account = module.service-account-restarter.email
@@ -145,7 +145,7 @@ module "cf-healthchecker" {
region = var.region
bucket_name = module.cf-restarter.bucket_name
bundle_config = {
- source_dir = "${path.module}/function/healthchecker"
+ path = "${path.module}/function/healthchecker"
output_path = "healthchecker.zip"
}
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 b279da9f4e..e14fe77d7f 100644
--- a/blueprints/networking/private-cloud-function-from-onprem/main.tf
+++ b/blueprints/networking/private-cloud-function-from-onprem/main.tf
@@ -184,7 +184,7 @@ module "function-hello" {
bucket_name = "${var.name}-tf-cf-deploy"
ingress_settings = "ALLOW_INTERNAL_ONLY"
bundle_config = {
- source_dir = "${path.module}/assets"
+ path = "${path.module}/assets"
output_path = "bundle.zip"
}
bucket_config = {
diff --git a/modules/cloud-function-v1/README.md b/modules/cloud-function-v1/README.md
index ebcf0dd0aa..cd8fbe8641 100644
--- a/modules/cloud-function-v1/README.md
+++ b/modules/cloud-function-v1/README.md
@@ -39,7 +39,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = var.bucket
bundle_config = {
- source_dir = "assets/sample-function/"
+ path = "assets/sample-function/"
output_path = "bundle.zip"
}
}
@@ -58,7 +58,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
trigger_config = {
@@ -81,7 +81,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
iam = {
@@ -107,7 +107,7 @@ module "cf-http" {
lifecycle_delete_age_days = 1
}
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
}
}
# tftest modules=1 resources=3 inventory=bucket-creation.yaml
@@ -125,7 +125,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
service_account_create = true
@@ -143,7 +143,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
service_account = "non-existent@serice.account.email"
@@ -153,6 +153,10 @@ module "cf-http" {
### Custom bundle config
+The Cloud Function bundle can be configured via the `bundle_config` variable, so that either a `zip` archive or a source folder can be used.
+
+If a `zip` archive is already available, simply set the archive path in `bundle_config.path`. If a dynamically generated archive is needed, set `bundle_config.path` to the source folder path, then optionally configure the path where the archive will be created, and any exclusions needed in the archive.
+
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.
```hcl
@@ -163,7 +167,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets/"
output_path = "bundle.zip"
excludes = ["__pycache__"]
}
@@ -184,7 +188,7 @@ module "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"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
}
@@ -203,7 +207,7 @@ module "cf-http-one" {
name = "test-cf-http-one"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets"
}
}
@@ -214,17 +218,20 @@ module "cf-http-two" {
name = "test-cf-http-two"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "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
+
+- `/app/secret/first` contains version 1
+- `/app/secret/second` contains version 2
+- `/app/secret/latest` contains latest version of the secret
+
```hcl
module "cf-http" {
source = "./fabric/modules/cloud-function-v1"
@@ -233,7 +240,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
secrets = {
@@ -261,6 +268,7 @@ module "cf-http" {
```
### 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.
```hcl
@@ -271,7 +279,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
kms_key = "projects/my-project/locations/europe-west1/keyRings/mykeyring/cryptoKeys/mykey"
@@ -287,7 +295,7 @@ module "cf-http" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [bucket_name](variables.tf#L26) | 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](variables.tf#L44) | Cloud function source folder and generated zip bundle paths. Output path defaults to '/tmp/bundle.zip' if null. | object({…})
| ✓ | |
+| [bundle_config](variables.tf#L44) | Cloud function source. If path points to a .zip archive it is uploaded as-is, otherwise an archive is created on the fly. A null output path will use a unique name for the bundle in /tmp. | object({…})
| ✓ | |
| [name](variables.tf#L115) | Name used for cloud function and associated resources. | string
| ✓ | |
| [project_id](variables.tf#L130) | Project id used for all resources. | string
| ✓ | |
| [region](variables.tf#L135) | Region used for all resources. | string
| ✓ | |
diff --git a/modules/cloud-function-v1/bundle.tf b/modules/cloud-function-v1/bundle.tf
new file mode 100644
index 0000000000..2553d23a6e
--- /dev/null
+++ b/modules/cloud-function-v1/bundle.tf
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+locals {
+ bundle = {
+ md5 = try(
+ data.archive_file.bundle[0].output_md5,
+ data.local_file.bundle[0].content_md5
+ )
+ path = try(
+ data.archive_file.bundle[0].output_path,
+ var.bundle_config.path
+ )
+ }
+}
+
+resource "google_storage_bucket" "bucket" {
+ count = var.bucket_config == null ? 0 : 1
+ project = var.project_id
+ name = "${local.prefix}${var.bucket_name}"
+ uniform_bucket_level_access = true
+ location = (
+ var.bucket_config.location == null
+ ? var.region
+ : var.bucket_config.location
+ )
+ labels = var.labels
+ dynamic "lifecycle_rule" {
+ for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
+ content {
+ action { type = "Delete" }
+ condition {
+ age = var.bucket_config.lifecycle_delete_age_days
+ with_state = "ARCHIVED"
+ }
+ }
+ }
+ dynamic "versioning" {
+ for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
+ content {
+ enabled = true
+ }
+ }
+}
+
+resource "google_storage_bucket_object" "bundle" {
+ name = "bundle-${local.bundle.md5}.zip"
+ bucket = local.bucket
+ source = local.bundle.path
+}
+
+data "archive_file" "bundle" {
+ count = (
+ try(fileexists(var.bundle_config.path), null) == null ? 1 : 0
+ )
+ type = "zip"
+ source_dir = var.bundle_config.path
+ output_path = coalesce(var.bundle_config.output_path, "/tmp/bundle-${var.project_id}-${var.name}.zip")
+ output_file_mode = "0644"
+ excludes = var.bundle_config.excludes
+}
+
+data "local_file" "bundle" {
+ count = (
+ try(fileexists(var.bundle_config.path), null) == null ? 0 : 1
+ )
+ filename = var.bundle_config.path
+}
diff --git a/modules/cloud-function-v1/main.tf b/modules/cloud-function-v1/main.tf
index 7a7fdc9152..bcc8cffa9c 100644
--- a/modules/cloud-function-v1/main.tf
+++ b/modules/cloud-function-v1/main.tf
@@ -41,7 +41,6 @@ locals {
)
}
-
resource "google_vpc_access_connector" "connector" {
count = try(var.vpc_connector.create, false) == false ? 0 : 1
project = var.project_id
@@ -132,54 +131,9 @@ resource "google_cloudfunctions_function_iam_binding" "default" {
members = each.value
}
-resource "google_storage_bucket" "bucket" {
- count = var.bucket_config == null ? 0 : 1
- project = var.project_id
- name = "${local.prefix}${var.bucket_name}"
- uniform_bucket_level_access = true
- location = (
- var.bucket_config.location == null
- ? var.region
- : var.bucket_config.location
- )
- labels = var.labels
-
- dynamic "lifecycle_rule" {
- for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
- content {
- action { type = "Delete" }
- condition {
- age = var.bucket_config.lifecycle_delete_age_days
- with_state = "ARCHIVED"
- }
- }
- }
-
- dynamic "versioning" {
- for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
- content {
- enabled = true
- }
- }
-}
-
-resource "google_storage_bucket_object" "bundle" {
- name = "bundle-${data.archive_file.bundle.output_md5}.zip"
- bucket = local.bucket
- source = data.archive_file.bundle.output_path
-}
-
-data "archive_file" "bundle" {
- type = "zip"
- source_dir = var.bundle_config.source_dir
- output_path = coalesce(var.bundle_config.output_path, "/tmp/bundle-${var.project_id}-${var.name}.zip")
- output_file_mode = "0644"
- excludes = var.bundle_config.excludes
-}
-
resource "google_service_account" "service_account" {
count = var.service_account_create ? 1 : 0
project = var.project_id
account_id = "tf-cf-${var.name}"
display_name = "Terraform Cloud Function ${var.name}."
-}
\ No newline at end of file
+}
diff --git a/modules/cloud-function-v1/variables.tf b/modules/cloud-function-v1/variables.tf
index 8dc592addd..a2c192140f 100644
--- a/modules/cloud-function-v1/variables.tf
+++ b/modules/cloud-function-v1/variables.tf
@@ -42,11 +42,11 @@ variable "build_worker_pool" {
}
variable "bundle_config" {
- description = "Cloud function source folder and generated zip bundle paths. Output path defaults to '/tmp/bundle.zip' if null."
+ description = "Cloud function source. If path points to a .zip archive it is uploaded as-is, otherwise an archive is created on the fly. A null output path will use a unique name for the bundle in /tmp."
type = object({
- source_dir = string
- output_path = optional(string)
+ path = string
excludes = optional(list(string))
+ output_path = optional(string)
})
}
diff --git a/modules/cloud-function-v2/README.md b/modules/cloud-function-v2/README.md
index f54dd50aec..78b05afcc2 100644
--- a/modules/cloud-function-v2/README.md
+++ b/modules/cloud-function-v2/README.md
@@ -38,7 +38,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
}
@@ -68,7 +68,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
trigger_config = {
@@ -95,7 +95,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
iam = {
@@ -121,7 +121,7 @@ module "cf-http" {
lifecycle_delete_age_days = 1
}
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
}
}
# tftest modules=1 resources=3 inventory=bucket-creation.yaml
@@ -139,7 +139,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
service_account_create = true
@@ -157,7 +157,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets/"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
service_account = "non-existent@serice.account.email"
@@ -167,6 +167,10 @@ module "cf-http" {
### Custom bundle config
+The Cloud Function bundle can be configured via the `bundle_config` variable, so that either a `zip` archive or a source folder can be used.
+
+If a `zip` archive is already available, simply set the archive path in `bundle_config.path`. If a dynamically generated archive is needed, set `bundle_config.path` to the source folder path, then optionally configure the path where the archive will be created, and any exclusions needed in the archive.
+
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.
```hcl
@@ -177,7 +181,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets/"
output_path = "bundle.zip"
excludes = ["__pycache__"]
}
@@ -198,7 +202,7 @@ module "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"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
}
@@ -217,7 +221,7 @@ module "cf-http-one" {
name = "test-cf-http-one"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets"
}
}
@@ -228,17 +232,20 @@ module "cf-http-two" {
name = "test-cf-http-two"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "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
+
+- `/app/secret/first` contains version 1
+- `/app/secret/second` contains version 2
+- `/app/secret/latest` contains latest version of the secret
+
```hcl
module "cf-http" {
source = "./fabric/modules/cloud-function-v2"
@@ -247,7 +254,7 @@ module "cf-http" {
name = "test-cf-http"
bucket_name = "test-cf-bundles"
bundle_config = {
- source_dir = "fabric/assets"
+ path = "fabric/assets/"
output_path = "bundle.zip"
}
secrets = {
@@ -280,7 +287,7 @@ module "cf-http" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [bucket_name](variables.tf#L26) | 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](variables.tf#L38) | Cloud function source folder and generated zip bundle paths. Output path defaults to '/tmp/bundle.zip' if null. | object({…})
| ✓ | |
+| [bundle_config](variables.tf#L38) | Cloud function source. If path points to a .zip archive it is uploaded as-is, otherwise an archive is created on the fly. A null output path will use a unique name for the bundle in /tmp. | object({…})
| ✓ | |
| [name](variables.tf#L109) | Name used for cloud function and associated resources. | string
| ✓ | |
| [project_id](variables.tf#L124) | Project id used for all resources. | string
| ✓ | |
| [region](variables.tf#L129) | Region used for all resources. | string
| ✓ | |
diff --git a/modules/cloud-function-v2/bundle.tf b/modules/cloud-function-v2/bundle.tf
new file mode 100644
index 0000000000..2553d23a6e
--- /dev/null
+++ b/modules/cloud-function-v2/bundle.tf
@@ -0,0 +1,81 @@
+/**
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+locals {
+ bundle = {
+ md5 = try(
+ data.archive_file.bundle[0].output_md5,
+ data.local_file.bundle[0].content_md5
+ )
+ path = try(
+ data.archive_file.bundle[0].output_path,
+ var.bundle_config.path
+ )
+ }
+}
+
+resource "google_storage_bucket" "bucket" {
+ count = var.bucket_config == null ? 0 : 1
+ project = var.project_id
+ name = "${local.prefix}${var.bucket_name}"
+ uniform_bucket_level_access = true
+ location = (
+ var.bucket_config.location == null
+ ? var.region
+ : var.bucket_config.location
+ )
+ labels = var.labels
+ dynamic "lifecycle_rule" {
+ for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
+ content {
+ action { type = "Delete" }
+ condition {
+ age = var.bucket_config.lifecycle_delete_age_days
+ with_state = "ARCHIVED"
+ }
+ }
+ }
+ dynamic "versioning" {
+ for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
+ content {
+ enabled = true
+ }
+ }
+}
+
+resource "google_storage_bucket_object" "bundle" {
+ name = "bundle-${local.bundle.md5}.zip"
+ bucket = local.bucket
+ source = local.bundle.path
+}
+
+data "archive_file" "bundle" {
+ count = (
+ try(fileexists(var.bundle_config.path), null) == null ? 1 : 0
+ )
+ type = "zip"
+ source_dir = var.bundle_config.path
+ output_path = coalesce(var.bundle_config.output_path, "/tmp/bundle-${var.project_id}-${var.name}.zip")
+ output_file_mode = "0644"
+ excludes = var.bundle_config.excludes
+}
+
+data "local_file" "bundle" {
+ count = (
+ try(fileexists(var.bundle_config.path), null) == null ? 0 : 1
+ )
+ filename = var.bundle_config.path
+}
diff --git a/modules/cloud-function-v2/main.tf b/modules/cloud-function-v2/main.tf
index 24046eada2..df445ffe17 100644
--- a/modules/cloud-function-v2/main.tf
+++ b/modules/cloud-function-v2/main.tf
@@ -191,51 +191,6 @@ resource "google_cloud_run_service_iam_member" "invoker" {
member = "serviceAccount:${local.trigger_sa_email}"
}
-resource "google_storage_bucket" "bucket" {
- count = var.bucket_config == null ? 0 : 1
- project = var.project_id
- name = "${local.prefix}${var.bucket_name}"
- uniform_bucket_level_access = true
- location = (
- var.bucket_config.location == null
- ? var.region
- : var.bucket_config.location
- )
- labels = var.labels
-
- dynamic "lifecycle_rule" {
- for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
- content {
- action { type = "Delete" }
- condition {
- age = var.bucket_config.lifecycle_delete_age_days
- with_state = "ARCHIVED"
- }
- }
- }
-
- dynamic "versioning" {
- for_each = var.bucket_config.lifecycle_delete_age_days == null ? [] : [""]
- content {
- enabled = true
- }
- }
-}
-
-resource "google_storage_bucket_object" "bundle" {
- name = "bundle-${data.archive_file.bundle.output_md5}.zip"
- bucket = local.bucket
- source = data.archive_file.bundle.output_path
-}
-
-data "archive_file" "bundle" {
- type = "zip"
- source_dir = var.bundle_config.source_dir
- output_path = coalesce(var.bundle_config.output_path, "/tmp/bundle-${var.project_id}-${var.name}.zip")
- output_file_mode = "0644"
- excludes = var.bundle_config.excludes
-}
-
resource "google_service_account" "service_account" {
count = var.service_account_create ? 1 : 0
project = var.project_id
diff --git a/modules/cloud-function-v2/variables.tf b/modules/cloud-function-v2/variables.tf
index 428ba8dba2..481de85528 100644
--- a/modules/cloud-function-v2/variables.tf
+++ b/modules/cloud-function-v2/variables.tf
@@ -36,11 +36,11 @@ variable "build_worker_pool" {
}
variable "bundle_config" {
- description = "Cloud function source folder and generated zip bundle paths. Output path defaults to '/tmp/bundle.zip' if null."
+ description = "Cloud function source. If path points to a .zip archive it is uploaded as-is, otherwise an archive is created on the fly. A null output path will use a unique name for the bundle in /tmp."
type = object({
- source_dir = string
- output_path = optional(string)
+ path = string
excludes = optional(list(string))
+ output_path = optional(string)
})
}