diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a382ff81b..3300a7de7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,53 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - + + +### BLUEPRINTS + +- [[#2395](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2395)] Fix tutorial error. ([wiktorn](https://github.com/wiktorn)) +- [[#2396](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2396)] Update `modules/artifact-registry` with newly-released features. ([juliocc](https://github.com/juliocc)) +- [[#2392](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2392)] Added forward_proxy_uri to apigee environments in apigee-x-foundation… ([apichick](https://github.com/apichick)) +- [[#2389](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2389)] Several wording and typos updates ([bluPhy](https://github.com/bluPhy)) +- [[#2382](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2382)] Fixes related to Apigee KMS keys ([apichick](https://github.com/apichick)) +- [[#2372](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2372)] Added spanner-instance module ([apichick](https://github.com/apichick)) + +### FAST + +- [[#2411](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2411)] [FAST] Fix IAM bindings to impersonate resman CICD SAs at bootstrap stage ([jayBana](https://github.com/jayBana)) +- [[#2404](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2404)] Documented new GCVE design options ([eliamaldini](https://github.com/eliamaldini)) +- [[#2402](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2402)] gitlab workflow template fixes #2401 ([sudhirrs](https://github.com/sudhirrs)) +- [[#2389](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2389)] Several wording and typos updates ([bluPhy](https://github.com/bluPhy)) +- [[#2378](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2378)] Add wording for SCC Enterprise to FAST stage 0 ([ludoo](https://github.com/ludoo)) + +### MODULES + +- [[#2409](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2409)] Adds support for external SPGs to net-firewall-policy ([LucaPrete](https://github.com/LucaPrete)) +- [[#2407](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2407)] Allow project factory projects to override name ([juliocc](https://github.com/juliocc)) +- [[#2405](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2405)] Adding placement_policy for GKE nodepools (ex: GPU compact placement or TPU topology) ([aurelienlegrand](https://github.com/aurelienlegrand)) +- [[#2400](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2400)] Add info about roles for connectors service agent ([wiktorn](https://github.com/wiktorn)) +- [[#2396](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2396)] Update `modules/artifact-registry` with newly-released features. ([juliocc](https://github.com/juliocc)) +- [[#2393](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2393)] Add support for SSL policy to net-lb-app-int module ([ludoo](https://github.com/ludoo)) +- [[#2387](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2387)] Added certificate-manager module ([apichick](https://github.com/apichick)) +- [[#2390](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2390)] Add AssuredWorkload support to the folder module ([averbuks](https://github.com/averbuks)) +- [[#2384](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2384)] Allow Cloud NAT to only use secondary ranges ([juliocc](https://github.com/juliocc)) +- [[#2388](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2388)] Added missing links to firestore module is READMEs. ([apichick](https://github.com/apichick)) +- [[#2389](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2389)] Several wording and typos updates ([bluPhy](https://github.com/bluPhy)) +- [[#2374](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2374)] Added firestore module ([apichick](https://github.com/apichick)) +- [[#2380](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2380)] Added private_endpoint_subnetwork parameters to GKE standard and autopilot modules ([luigi-bitonti](https://github.com/luigi-bitonti)) +- [[#2370](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2370)] Apigee - Add forward_proxy_uri support on environment resource ([diogo-j-n-teixeira](https://github.com/diogo-j-n-teixeira)) +- [[#2376](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2376)] Removed advertised_groups ALL_VPC_SUBNETS, ALL_VPC_SUBNETS as they ar… ([apichick](https://github.com/apichick)) +- [[#2375](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2375)] Minor fixes in workstations IAM ([apichick](https://github.com/apichick)) +- [[#2372](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2372)] Added spanner-instance module ([apichick](https://github.com/apichick)) +- [[#2373](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2373)] Added expire_time option to the secret-manager module ([deanosaurx](https://github.com/deanosaurx)) +- [[#2371](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2371)] Support build service account in cloud function v2 module ([ludoo](https://github.com/ludoo)) +- [[#2369](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2369)] Add example, tests and fix for Google APIs PSC endpoint ([wiktorn](https://github.com/wiktorn)) +- [[#2368](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2368)] Fix for plan not in sync when creating billing budgets in project factory #2365 ([sudhirrs](https://github.com/sudhirrs)) +- [[#2366](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2366)] Added additional range field to GKE standand and autopilot ([luigi-bitonti](https://github.com/luigi-bitonti)) + +### TOOLS + +- [[#2399](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/2399)] Test different versions of Terraform ([wiktorn](https://github.com/wiktorn)) ## [32.0.0] - 2024-06-16 diff --git a/fast/assets/templates/workflow-github.yaml b/fast/assets/templates/workflow-github.yaml index 0b73601b51..378ea1762c 100644 --- a/fast/assets/templates/workflow-github.yaml +++ b/fast/assets/templates/workflow-github.yaml @@ -30,7 +30,7 @@ env: SSH_AUTH_SOCK: /tmp/ssh_agent.sock TF_PROVIDERS_FILE: ${tf_providers_files.apply} TF_PROVIDERS_FILE_PLAN: ${tf_providers_files.plan} - TF_VERSION: 1.6.5 + TF_VERSION: 1.7.4 jobs: fast-pr: @@ -49,7 +49,7 @@ jobs: steps: - id: checkout name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # set up SSH key authentication to the modules repository @@ -106,7 +106,7 @@ jobs: - id: tf-setup name: Set up Terraform - uses: hashicorp/setup-terraform@v2.0.3 + uses: hashicorp/setup-terraform@v3 with: terraform_version: $${{env.TF_VERSION}} @@ -142,7 +142,7 @@ jobs: - id: pr-comment name: Post comment to Pull Request continue-on-error: true - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' env: PLAN: $${{steps.tf-plan.outputs.stdout}}\n$${{steps.tf-plan.outputs.stderr}} @@ -183,7 +183,7 @@ jobs: - id: pr-short-comment name: Post comment to Pull Request (abbreviated) - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' && steps.pr-comment.outcome != 'success' with: script: | diff --git a/fast/assets/templates/workflow-sourcerepo.yaml b/fast/assets/templates/workflow-sourcerepo.yaml deleted file mode 100644 index 88c04fac59..0000000000 --- a/fast/assets/templates/workflow-sourcerepo.yaml +++ /dev/null @@ -1,98 +0,0 @@ -# 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. - -steps: - - name: alpine:3 - id: tf-download - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - mkdir -p /builder/home/.local/bin - wget https://releases.hashicorp.com/terraform/$${_TF_VERSION}/terraform_$${_TF_VERSION}_linux_amd64.zip - unzip terraform_$${_TF_VERSION}_linux_amd64.zip -d /builder/home/.local/bin - rm terraform_$${_TF_VERSION}_linux_amd64.zip - chmod 755 /builder/home/.local/bin/terraform - - name: alpine:3 - id: tf-check-format - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform fmt -recursive -check /workspace/ - - name: gcr.io/google.com/cloudsdktool/cloud-sdk:alpine - id: tf-files - entrypoint: bash - args: - - -eEuo - - pipefail - - -c - - |- - /google-cloud-sdk/bin/gsutil cp \ - gs://$${_FAST_OUTPUTS_BUCKET}/providers/$${_TF_PROVIDERS_FILE} ./ - /google-cloud-sdk/bin/gsutil cp -r \ - gs://$${_FAST_OUTPUTS_BUCKET}/tfvars ./ - for f in $${_TF_VAR_FILES}; do - ln -s tfvars/$f ./ - done - - name: alpine:3 - id: tf-init - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform init -no-color - - name: alpine:3 - id: tf-check-validate - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform validate -no-color - - name: alpine:3 - id: tf-plan - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform plan -no-color -input=false -out plan.out - # store artifact and ask for approval here if needed - - name: alpine:3 - id: tf-apply - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform apply -no-color -input=false -auto-approve plan.out -options: - env: - - PATH=/usr/local/bin:/usr/bin:/bin:/builder/home/.local/bin - logging: CLOUD_LOGGING_ONLY -substitutions: - _FAST_OUTPUTS_BUCKET: ${outputs_bucket} - _TF_PROVIDERS_FILE: ${tf_providers_file.apply} - _TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)} - _TF_VERSION: 1.4.4 diff --git a/fast/extras/0-cicd-github/main.tf b/fast/extras/0-cicd-github/main.tf index bf58c10b4f..e0657233a1 100644 --- a/fast/extras/0-cicd-github/main.tf +++ b/fast/extras/0-cicd-github/main.tf @@ -18,6 +18,7 @@ locals { _repository_files = flatten([ for k, v in var.repositories : [ for f in concat( + [for f in fileset(path.module, "${v.populate_from}/*.png") : f], [for f in fileset(path.module, "${v.populate_from}/*.svg") : f], [for f in fileset(path.module, "${v.populate_from}/*.md") : f], (v.populate_samples ? [for f in fileset(path.module, "${v.populate_from}/*.sample") : f] : []), @@ -167,7 +168,7 @@ resource "github_repository_file" "default" { "/source(\\s*)=\\s*\"../../../modules/([^/\"]+)\"/", "source$1= \"git@github.com:${local.modules_repo}.git//${local.module_prefix}$2${local.modules_ref}\"" # " ) - : file(each.value.file) + : try(file(each.value.file), filebase64(each.value.file)) ) commit_message = "${var.commit_config.message} (${each.value.name})" commit_author = var.commit_config.author diff --git a/fast/stages/0-bootstrap/automation.tf b/fast/stages/0-bootstrap/automation.tf index bd7ce232c5..19cac5c819 100644 --- a/fast/stages/0-bootstrap/automation.tf +++ b/fast/stages/0-bootstrap/automation.tf @@ -272,13 +272,13 @@ module "automation-tf-resman-sa" { # we use additive IAM to allow tenant CI/CD SAs to impersonate it iam_bindings_additive = merge( local.cicd_resman_sa == "" ? {} : { - cicd_token_creator = { + cicd_token_creator_resman = { member = local.cicd_resman_sa role = "roles/iam.serviceAccountTokenCreator" } }, local.cicd_tenants_sa == "" ? {} : { - cicd_token_creator = { + cicd_token_creator_tenants = { member = local.cicd_tenants_sa role = "roles/iam.serviceAccountTokenCreator" } @@ -299,13 +299,13 @@ module "automation-tf-resman-r-sa" { # we use additive IAM to allow tenant CI/CD SAs to impersonate it iam_bindings_additive = merge( local.cicd_resman_r_sa == "" ? {} : { - cicd_token_creator = { + cicd_token_creator_resman = { member = local.cicd_resman_r_sa role = "roles/iam.serviceAccountTokenCreator" } }, local.cicd_tenants_r_sa == "" ? {} : { - cicd_token_creator = { + cicd_token_creator_tenants = { member = local.cicd_tenants_r_sa role = "roles/iam.serviceAccountTokenCreator" } diff --git a/fast/stages/0-bootstrap/templates/workflow-github.yaml b/fast/stages/0-bootstrap/templates/workflow-github.yaml index bbe90a8f18..bec19b711f 100644 --- a/fast/stages/0-bootstrap/templates/workflow-github.yaml +++ b/fast/stages/0-bootstrap/templates/workflow-github.yaml @@ -142,7 +142,7 @@ jobs: - id: pr-comment name: Post comment to Pull Request continue-on-error: true - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' env: PLAN: $${{steps.tf-plan.outputs.stdout}}\n$${{steps.tf-plan.outputs.stderr}} @@ -183,7 +183,7 @@ jobs: - id: pr-short-comment name: Post comment to Pull Request (abbreviated) - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' && steps.pr-comment.outcome != 'success' with: script: | diff --git a/fast/stages/0-bootstrap/templates/workflow-sourcerepo.yaml b/fast/stages/0-bootstrap/templates/workflow-sourcerepo.yaml deleted file mode 100644 index 012ff93e79..0000000000 --- a/fast/stages/0-bootstrap/templates/workflow-sourcerepo.yaml +++ /dev/null @@ -1,98 +0,0 @@ -# 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. - -steps: - - name: alpine:3 - id: tf-download - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - mkdir -p /builder/home/.local/bin - wget https://releases.hashicorp.com/terraform/$${_TF_VERSION}/terraform_$${_TF_VERSION}_linux_amd64.zip - unzip terraform_$${_TF_VERSION}_linux_amd64.zip -d /builder/home/.local/bin - rm terraform_$${_TF_VERSION}_linux_amd64.zip - chmod 755 /builder/home/.local/bin/terraform - - name: alpine:3 - id: tf-check-format - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform fmt -recursive -check /workspace/ - - name: gcr.io/google.com/cloudsdktool/cloud-sdk:alpine - id: tf-files - entrypoint: bash - args: - - -eEuo - - pipefail - - -c - - |- - /google-cloud-sdk/bin/gsutil cp \ - gs://$${_FAST_OUTPUTS_BUCKET}/providers/$${_TF_PROVIDERS_FILE} ./ - /google-cloud-sdk/bin/gsutil cp -r \ - gs://$${_FAST_OUTPUTS_BUCKET}/tfvars ./ - for f in $${_TF_VAR_FILES}; do - ln -s tfvars/$f ./ - done - - name: alpine:3 - id: tf-init - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform init -no-color - - name: alpine:3 - id: tf-check-validate - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform validate -no-color - - name: alpine:3 - id: tf-plan - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform plan -no-color -input=false -out plan.out - # store artifact and ask for approval here if needed - - name: alpine:3 - id: tf-apply - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform apply -no-color -input=false -auto-approve plan.out -options: - env: - - PATH=/usr/local/bin:/usr/bin:/bin:/builder/home/.local/bin - logging: CLOUD_LOGGING_ONLY -substitutions: - _FAST_OUTPUTS_BUCKET: ${outputs_bucket} - _TF_PROVIDERS_FILE: ${tf_providers_files.apply} - _TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)} - _TF_VERSION: 1.7.6 diff --git a/fast/stages/1-resman/templates/workflow-github.yaml b/fast/stages/1-resman/templates/workflow-github.yaml index 460bbf90d3..378ea1762c 100644 --- a/fast/stages/1-resman/templates/workflow-github.yaml +++ b/fast/stages/1-resman/templates/workflow-github.yaml @@ -142,7 +142,7 @@ jobs: - id: pr-comment name: Post comment to Pull Request continue-on-error: true - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' env: PLAN: $${{steps.tf-plan.outputs.stdout}}\n$${{steps.tf-plan.outputs.stderr}} @@ -183,7 +183,7 @@ jobs: - id: pr-short-comment name: Post comment to Pull Request (abbreviated) - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' && steps.pr-comment.outcome != 'success' with: script: | diff --git a/fast/stages/1-resman/templates/workflow-sourcerepo.yaml b/fast/stages/1-resman/templates/workflow-sourcerepo.yaml deleted file mode 100644 index 012ff93e79..0000000000 --- a/fast/stages/1-resman/templates/workflow-sourcerepo.yaml +++ /dev/null @@ -1,98 +0,0 @@ -# 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. - -steps: - - name: alpine:3 - id: tf-download - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - mkdir -p /builder/home/.local/bin - wget https://releases.hashicorp.com/terraform/$${_TF_VERSION}/terraform_$${_TF_VERSION}_linux_amd64.zip - unzip terraform_$${_TF_VERSION}_linux_amd64.zip -d /builder/home/.local/bin - rm terraform_$${_TF_VERSION}_linux_amd64.zip - chmod 755 /builder/home/.local/bin/terraform - - name: alpine:3 - id: tf-check-format - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform fmt -recursive -check /workspace/ - - name: gcr.io/google.com/cloudsdktool/cloud-sdk:alpine - id: tf-files - entrypoint: bash - args: - - -eEuo - - pipefail - - -c - - |- - /google-cloud-sdk/bin/gsutil cp \ - gs://$${_FAST_OUTPUTS_BUCKET}/providers/$${_TF_PROVIDERS_FILE} ./ - /google-cloud-sdk/bin/gsutil cp -r \ - gs://$${_FAST_OUTPUTS_BUCKET}/tfvars ./ - for f in $${_TF_VAR_FILES}; do - ln -s tfvars/$f ./ - done - - name: alpine:3 - id: tf-init - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform init -no-color - - name: alpine:3 - id: tf-check-validate - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform validate -no-color - - name: alpine:3 - id: tf-plan - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform plan -no-color -input=false -out plan.out - # store artifact and ask for approval here if needed - - name: alpine:3 - id: tf-apply - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform apply -no-color -input=false -auto-approve plan.out -options: - env: - - PATH=/usr/local/bin:/usr/bin:/bin:/builder/home/.local/bin - logging: CLOUD_LOGGING_ONLY -substitutions: - _FAST_OUTPUTS_BUCKET: ${outputs_bucket} - _TF_PROVIDERS_FILE: ${tf_providers_files.apply} - _TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)} - _TF_VERSION: 1.7.6 diff --git a/fast/stages/1-tenant-factory/templates/workflow-github.yaml b/fast/stages/1-tenant-factory/templates/workflow-github.yaml index bbe90a8f18..378ea1762c 100644 --- a/fast/stages/1-tenant-factory/templates/workflow-github.yaml +++ b/fast/stages/1-tenant-factory/templates/workflow-github.yaml @@ -39,7 +39,7 @@ jobs: github.event.action == 'closed' && github.event.pull_request.merged == true || github.event.action == 'opened' || - github.event.action == 'synchronize' + github.event.action == 'synchronize' permissions: contents: read id-token: write @@ -142,7 +142,7 @@ jobs: - id: pr-comment name: Post comment to Pull Request continue-on-error: true - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' env: PLAN: $${{steps.tf-plan.outputs.stdout}}\n$${{steps.tf-plan.outputs.stderr}} @@ -183,7 +183,7 @@ jobs: - id: pr-short-comment name: Post comment to Pull Request (abbreviated) - uses: actions/github-script@v6 + uses: actions/github-script@v7 if: github.event_name == 'pull_request' && steps.pr-comment.outcome != 'success' with: script: | diff --git a/fast/stages/1-tenant-factory/templates/workflow-sourcerepo.yaml b/fast/stages/1-tenant-factory/templates/workflow-sourcerepo.yaml deleted file mode 100644 index 012ff93e79..0000000000 --- a/fast/stages/1-tenant-factory/templates/workflow-sourcerepo.yaml +++ /dev/null @@ -1,98 +0,0 @@ -# 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. - -steps: - - name: alpine:3 - id: tf-download - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - mkdir -p /builder/home/.local/bin - wget https://releases.hashicorp.com/terraform/$${_TF_VERSION}/terraform_$${_TF_VERSION}_linux_amd64.zip - unzip terraform_$${_TF_VERSION}_linux_amd64.zip -d /builder/home/.local/bin - rm terraform_$${_TF_VERSION}_linux_amd64.zip - chmod 755 /builder/home/.local/bin/terraform - - name: alpine:3 - id: tf-check-format - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform fmt -recursive -check /workspace/ - - name: gcr.io/google.com/cloudsdktool/cloud-sdk:alpine - id: tf-files - entrypoint: bash - args: - - -eEuo - - pipefail - - -c - - |- - /google-cloud-sdk/bin/gsutil cp \ - gs://$${_FAST_OUTPUTS_BUCKET}/providers/$${_TF_PROVIDERS_FILE} ./ - /google-cloud-sdk/bin/gsutil cp -r \ - gs://$${_FAST_OUTPUTS_BUCKET}/tfvars ./ - for f in $${_TF_VAR_FILES}; do - ln -s tfvars/$f ./ - done - - name: alpine:3 - id: tf-init - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform init -no-color - - name: alpine:3 - id: tf-check-validate - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform validate -no-color - - name: alpine:3 - id: tf-plan - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform plan -no-color -input=false -out plan.out - # store artifact and ask for approval here if needed - - name: alpine:3 - id: tf-apply - entrypoint: sh - args: - - -eEuo - - pipefail - - -c - - |- - terraform apply -no-color -input=false -auto-approve plan.out -options: - env: - - PATH=/usr/local/bin:/usr/bin:/bin:/builder/home/.local/bin - logging: CLOUD_LOGGING_ONLY -substitutions: - _FAST_OUTPUTS_BUCKET: ${outputs_bucket} - _TF_PROVIDERS_FILE: ${tf_providers_files.apply} - _TF_VAR_FILES: ${tf_var_files == [] ? "''" : join("\n ", tf_var_files)} - _TF_VERSION: 1.7.6 diff --git a/modules/cloud-function-v1/README.md b/modules/cloud-function-v1/README.md index 5fb264ace4..d5431854a6 100644 --- a/modules/cloud-function-v1/README.md +++ b/modules/cloud-function-v1/README.md @@ -17,6 +17,7 @@ Cloud Function management, with support for IAM roles, optional bucket creation - [Using CMEK to encrypt function resources](#using-cmek-to-encrypt-function-resources) - [Variables](#variables) - [Outputs](#outputs) +- [Fixtures](#fixtures) ## TODO @@ -33,14 +34,14 @@ This deploys a Cloud Function with an HTTP endpoint, using a pre-existing GCS bu module "cf-http" { source = "./fabric/modules/cloud-function-v1" project_id = var.project_id - region = "europe-west1" + region = var.regions.secondary name = "test-cf-http" bucket_name = var.bucket bundle_config = { path = "assets/sample-function/" } } -# tftest modules=1 resources=2 e2e +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### PubSub and non-HTTP triggers @@ -50,19 +51,19 @@ Other trigger types other than HTTP are configured via the `trigger_config` vari ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { path = "assets/sample-function/" } trigger_config = { event = "google.pubsub.topic.publish" - resource = "local.my-topic" + resource = module.pubsub.topic.name } } -# tftest modules=1 resources=2 +# tftest modules=2 resources=7 fixtures=fixtures/pubsub.tf,fixtures/functions-default-sa-iam-grants.tf e2e ``` ### Controlling HTTP access @@ -72,10 +73,10 @@ To allow anonymous access to the function, grant the `roles/cloudfunctions.invok ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { path = "assets/sample-function/" } @@ -83,7 +84,7 @@ module "cf-http" { "roles/cloudfunctions.invoker" = ["allUsers"] } } -# tftest modules=1 resources=3 inventory=iam.yaml +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=iam.yaml e2e ``` ### GCS bucket creation @@ -93,19 +94,20 @@ You can have the module auto-create the GCS bucket used for deployment via the ` ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" - prefix = "my-prefix" + project_id = var.project_id + region = var.regions.secondary + prefix = var.prefix name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bucket_config = { + force_destroy = true lifecycle_delete_age_days = 1 } bundle_config = { path = "assets/sample-function/" } } -# tftest modules=1 resources=3 inventory=bucket-creation.yaml +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=bucket-creation.yaml e2e ``` ### Service account management @@ -115,16 +117,16 @@ To use a custom service account managed by the module, set `service_account_crea ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { path = "assets/sample-function/" } service_account_create = true } -# tftest modules=1 resources=3 +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` To use an externally managed service account, pass its email in `service_account` and leave `service_account_create` to `false` (the default). @@ -132,16 +134,16 @@ To use an externally managed service account, pass its email in `service_account ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { path = "assets/sample-function/" } - service_account = "non-existent@serice.account.email" + service_account = var.service_account.email } -# tftest modules=1 resources=2 +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### Custom bundle config @@ -157,19 +159,19 @@ When a GCS URI or a local zip file are used, a change in their names will trigge ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" folder_options = { archive_path = "bundle.zip" excludes = ["__pycache__"] } } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### Private Cloud Build Pool @@ -179,16 +181,16 @@ This deploys a Cloud Function with an HTTP endpoint, using a pre-existing GCS bu ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" - build_worker_pool = "projects/my-project/locations/europe-west1/workerPools/my_build_worker_pool" + bucket_name = var.bucket + build_worker_pool = google_cloudbuild_worker_pool.pool.id bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=6 fixtures=fixtures/cloudbuild-custom-pool.tf,fixtures/functions-default-sa-iam-grants.tf e2e ``` ### Multiple Cloud Functions within project @@ -198,68 +200,64 @@ When deploying multiple functions do not reuse `bundle_config.archive_path` betw ```hcl module "cf-http-one" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http-one" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } } module "cf-http-two" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http-two" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } } -# tftest modules=2 resources=4 inventory=multiple_functions.yaml +# tftest modules=2 resources=7 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=multiple_functions.yaml e2e ``` ### 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/ver1` contains version referenced by `module.secret-manager.version_versions["credentials:v1"]` ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } secrets = { VARIABLE_SECRET = { is_volume = false - project_id = 1234567890 - secret = "var_secret" + project_id = var.project_number # use project_number to avoid perm-diff + secret = reverse(split("/", module.secret-manager.secrets["credentials"].name))[0] versions = [ "latest" ] } "/app/secret" = { is_volume = true - project_id = 1234567890 - secret = "path_secret" + project_id = var.project_number # use project_number to avoid perm-diff + secret = reverse(split("/", module.secret-manager.secrets["credentials"].name))[0] versions = [ - "1:first", - "2:second", - "latest:latest" + "${module.secret-manager.version_versions["credentials:v1"]}:/ver1" ] } } } -# tftest modules=1 resources=2 inventory=secrets.yaml +# tftest modules=2 resources=8 fixtures=fixtures/secret-credentials.tf,fixtures/functions-default-sa-iam-grants.tf inventory=secrets.yaml e2e ``` ### Using CMEK to encrypt function resources @@ -267,51 +265,82 @@ module "cf-http" { This encrypt bucket _gcf-sources-*_ with the provided kms key. The repository has to be encrypted with the same kms key. ```hcl +module "kms" { + source = "./fabric/modules/kms" + project_id = var.project_id + keyring = { + location = var.regions.secondary + name = "function-cmek" + } + keys = { + "key" = {} + } + iam = { + "roles/cloudkms.cryptoKeyEncrypterDecrypter" = [ + "serviceAccount:service-${var.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gcp-sa-artifactregistry.iam.gserviceaccount.com", + "serviceAccount:service-${var.project_number}@gs-project-accounts.iam.gserviceaccount.com", + ] + } +} + +module "artifact-registry" { + source = "./fabric/modules/artifact-registry" + project_id = var.project_id + location = var.regions.secondary + name = "registry" + format = { docker = { standard = {} } } + encryption_key = module.kms.key_ids["key"] + depends_on = [ + module.kms + ] +} + module "cf-http" { source = "./fabric/modules/cloud-function-v1" - project_id = "my-project" - region = "europe-west1" + project_id = var.project_id + region = var.regions.secondary name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } - kms_key = "projects/my-project/locations/europe-west1/keyRings/mykeyring/cryptoKeys/mykey" + kms_key = module.kms.key_ids["key"] repository_settings = { - repository = "projects/my-project/locations/europe-west1/repositories/myrepo" + repository = module.artifact-registry.id } } -# tftest modules=1 resources=2 +# tftest modules=3 resources=9 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ## Variables | 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. Path can point to a GCS object URI, or a local path. A local path to a zip archive will generate a GCS object using its basename, a folder will be zipped and the GCS object name inferred when not specified. | object({…}) | ✓ | | -| [name](variables.tf#L139) | Name used for cloud function and associated resources. | string | ✓ | | -| [project_id](variables.tf#L154) | Project id used for all resources. | string | ✓ | | -| [region](variables.tf#L159) | Region used for all resources. | string | ✓ | | -| [bucket_config](variables.tf#L17) | Enable and configure auto-created bucket. Set fields to null to use defaults. | object({…}) | | null | -| [build_environment_variables](variables.tf#L32) | A set of key/value environment variable pairs available during build time. | map(string) | | {} | -| [build_worker_pool](variables.tf#L38) | Build worker pool, in projects//locations//workerPools/ format. | string | | null | -| [description](variables.tf#L77) | Optional description. | string | | "Terraform managed." | -| [environment_variables](variables.tf#L83) | Cloud function environment variables. | map(string) | | {} | -| [function_config](variables.tf#L89) | Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout. | object({…}) | | {…} | -| [https_security_level](variables.tf#L109) | The security level for the function: Allowed values are SECURE_ALWAYS, SECURE_OPTIONAL. | string | | null | -| [iam](variables.tf#L115) | IAM bindings for topic in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [ingress_settings](variables.tf#L121) | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . | string | | null | -| [kms_key](variables.tf#L127) | 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](variables.tf#L133) | Resource labels. | map(string) | | {} | -| [prefix](variables.tf#L144) | Optional prefix used for resource names. | string | | null | -| [repository_settings](variables.tf#L164) | 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](variables.tf#L175) | Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format. | map(object({…})) | | {} | -| [service_account](variables.tf#L187) | Service account email. Unused if service account is auto-created. | string | | null | -| [service_account_create](variables.tf#L193) | Auto-create service account. | bool | | false | -| [trigger_config](variables.tf#L199) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | -| [vpc_connector](variables.tf#L209) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | object({…}) | | null | -| [vpc_connector_config](variables.tf#L219) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null | +| [bucket_name](variables.tf#L27) | 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#L45) | Cloud function source. Path can point to a GCS object URI, or a local path. A local path to a zip archive will generate a GCS object using its basename, a folder will be zipped and the GCS object name inferred when not specified. | object({…}) | ✓ | | +| [name](variables.tf#L140) | Name used for cloud function and associated resources. | string | ✓ | | +| [project_id](variables.tf#L155) | Project id used for all resources. | string | ✓ | | +| [region](variables.tf#L160) | Region used for all resources. | string | ✓ | | +| [bucket_config](variables.tf#L17) | Enable and configure auto-created bucket. Set fields to null to use defaults. | object({…}) | | null | +| [build_environment_variables](variables.tf#L33) | A set of key/value environment variable pairs available during build time. | map(string) | | {} | +| [build_worker_pool](variables.tf#L39) | Build worker pool, in projects//locations//workerPools/ format. | string | | null | +| [description](variables.tf#L78) | Optional description. | string | | "Terraform managed." | +| [environment_variables](variables.tf#L84) | Cloud function environment variables. | map(string) | | {} | +| [function_config](variables.tf#L90) | Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout. | object({…}) | | {…} | +| [https_security_level](variables.tf#L110) | The security level for the function: Allowed values are SECURE_ALWAYS, SECURE_OPTIONAL. | string | | null | +| [iam](variables.tf#L116) | IAM bindings for topic in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [ingress_settings](variables.tf#L122) | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . | string | | null | +| [kms_key](variables.tf#L128) | 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](variables.tf#L134) | Resource labels. | map(string) | | {} | +| [prefix](variables.tf#L145) | Optional prefix used for resource names. | string | | null | +| [repository_settings](variables.tf#L165) | 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](variables.tf#L176) | Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format. | map(object({…})) | | {} | +| [service_account](variables.tf#L188) | Service account email. Unused if service account is auto-created. | string | | null | +| [service_account_create](variables.tf#L194) | Auto-create service account. | bool | | false | +| [trigger_config](variables.tf#L200) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | +| [vpc_connector](variables.tf#L210) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | object({…}) | | null | +| [vpc_connector_config](variables.tf#L220) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null | ## Outputs @@ -326,4 +355,11 @@ module "cf-http" { | [service_account_email](outputs.tf#L49) | Service account email. | | | [service_account_iam_email](outputs.tf#L54) | Service account email. | | | [vpc_connector](outputs.tf#L62) | VPC connector resource if created. | | + +## Fixtures + +- [cloudbuild-custom-pool.tf](../../tests/fixtures/cloudbuild-custom-pool.tf) +- [functions-default-sa-iam-grants.tf](../../tests/fixtures/functions-default-sa-iam-grants.tf) +- [pubsub.tf](../../tests/fixtures/pubsub.tf) +- [secret-credentials.tf](../../tests/fixtures/secret-credentials.tf) diff --git a/modules/cloud-function-v1/bundle.tf b/modules/cloud-function-v1/bundle.tf index 43ad5c8ee2..661ece8423 100644 --- a/modules/cloud-function-v1/bundle.tf +++ b/modules/cloud-function-v1/bundle.tf @@ -54,6 +54,7 @@ resource "google_storage_bucket" "bucket" { enabled = true } } + force_destroy = var.bucket_config.force_destroy } # compress bundle in a zip archive if it's a folder diff --git a/modules/cloud-function-v1/variables.tf b/modules/cloud-function-v1/variables.tf index 1c7c7e433d..d29d5e0cd6 100644 --- a/modules/cloud-function-v1/variables.tf +++ b/modules/cloud-function-v1/variables.tf @@ -17,8 +17,9 @@ variable "bucket_config" { description = "Enable and configure auto-created bucket. Set fields to null to use defaults." type = object({ - location = optional(string) + force_destroy = optional(bool) lifecycle_delete_age_days = optional(number) + location = optional(string) }) default = null } @@ -176,7 +177,7 @@ variable "secrets" { description = "Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format." type = map(object({ is_volume = bool - project_id = number + project_id = string secret = string versions = list(string) })) diff --git a/modules/cloud-function-v2/README.md b/modules/cloud-function-v2/README.md index 0c68b2eb17..45a9a66884 100644 --- a/modules/cloud-function-v2/README.md +++ b/modules/cloud-function-v2/README.md @@ -16,6 +16,7 @@ Cloud Function management, with support for IAM roles, optional bucket creation - [Mounting secrets from Secret Manager](#mounting-secrets-from-secret-manager) - [Variables](#variables) - [Outputs](#outputs) +- [Fixtures](#fixtures) ## TODO @@ -31,15 +32,15 @@ This deploys a Cloud Function with an HTTP endpoint, using a pre-existing GCS bu ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### PubSub and non-HTTP triggers @@ -49,10 +50,10 @@ Other trigger types other than HTTP are configured via the `trigger_config` vari ```hcl module "trigger-service-account" { source = "./fabric/modules/iam-service-account" - project_id = "my-project" + project_id = var.project_id name = "sa-cloudfunction" iam_project_roles = { - "my-project" = [ + (var.project_id) = [ "roles/run.invoker" ] } @@ -60,20 +61,20 @@ module "trigger-service-account" { module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } trigger_config = { event_type = "google.cloud.pubsub.topic.v1.messagePublished" - pubsub_topic = "local.my-topic" + pubsub_topic = module.pubsub.topic.id service_account_email = module.trigger-service-account.email } } -# tftest modules=2 resources=4 +# tftest modules=3 resources=9 fixtures=fixtures/pubsub.tf,fixtures/functions-default-sa-iam-grants.tf e2e ``` Ensure that pubsub service identity (`service-[project number]@gcp-sa-pubsub.iam.gserviceaccount.com` has `roles/iam.serviceAccountTokenCreator` @@ -86,18 +87,18 @@ To allow anonymous access to the function, grant the `roles/run.invoker` role to ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } iam = { "roles/run.invoker" = ["allUsers"] } } -# tftest modules=1 resources=3 inventory=iam.yaml +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=iam.yaml e2e ``` ### GCS bucket creation @@ -107,19 +108,20 @@ You can have the module auto-create the GCS bucket used for deployment via the ` ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region - prefix = "my-prefix" + prefix = var.prefix name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bucket_config = { + force_destroy = true lifecycle_delete_age_days = 1 } bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } } -# tftest modules=1 resources=3 inventory=bucket-creation.yaml +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=bucket-creation.yaml e2e ``` ### Service account management @@ -129,16 +131,16 @@ To use a custom service account managed by the module, set `service_account_crea ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } service_account_create = true } -# tftest modules=1 resources=3 +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` To use an externally managed service account, pass its email in `service_account` and leave `service_account_create` to `false` (the default). @@ -146,16 +148,16 @@ To use an externally managed service account, pass its email in `service_account ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } - service_account = "non-existent@serice.account.email" + service_account = var.service_account.email } -# tftest modules=1 resources=2 +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### Custom bundle config @@ -171,19 +173,19 @@ When a GCS URI or a local zip file are used, a change in their names will trigge ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" folder_options = { archive_path = "bundle.zip" excludes = ["__pycache__"] } } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=5 fixtures=fixtures/functions-default-sa-iam-grants.tf e2e ``` ### Private Cloud Build Pool @@ -193,16 +195,16 @@ This deploys a Cloud Function with an HTTP endpoint, using a pre-existing GCS bu ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" - build_worker_pool = "projects/my-project/locations/europe-west1/workerPools/my_build_worker_pool" + bucket_name = var.bucket + build_worker_pool = google_cloudbuild_worker_pool.pool.id bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=6 fixtures=fixtures/functions-default-sa-iam-grants.tf,fixtures/cloudbuild-custom-pool.tf e2e ``` ### Multiple Cloud Functions within project @@ -212,98 +214,95 @@ When deploying multiple functions via local folders do not reuse `bundle_config. ```hcl module "cf-http-one" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http-one" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets" + path = "assets/sample-function/" } } module "cf-http-two" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http-two" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets" + path = "assets/sample-function/" } } -# tftest modules=2 resources=4 inventory=multiple_functions.yaml +# tftest modules=2 resources=7 fixtures=fixtures/functions-default-sa-iam-grants.tf inventory=multiple_functions.yaml e2e ``` ### 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/ver1` contains version referenced by `module.secret-manager.version_versions["credentials:v1"]` ```hcl module "cf-http" { source = "./fabric/modules/cloud-function-v2" - project_id = "my-project" + project_id = var.project_id region = var.region name = "test-cf-http" - bucket_name = "test-cf-bundles" + bucket_name = var.bucket bundle_config = { - path = "fabric/assets/" + path = "assets/sample-function/" } secrets = { VARIABLE_SECRET = { is_volume = false - project_id = 1234567890 - secret = "var_secret" + project_id = var.project_id + secret = reverse(split("/", module.secret-manager.secrets["credentials"].name))[0] versions = [ "latest" ] } "/app/secret" = { is_volume = true - project_id = 1234567890 - secret = "path_secret" + project_id = var.project_id + secret = reverse(split("/", module.secret-manager.secrets["credentials"].name))[0] versions = [ - "1:first", - "2:second", - "latest:latest" + "${module.secret-manager.version_versions["credentials:v1"]}:ver1" ] } } } -# tftest modules=1 resources=2 inventory=secrets.yaml +# tftest modules=2 resources=8 fixtures=fixtures/secret-credentials.tf,fixtures/functions-default-sa-iam-grants.tf inventory=secrets.yaml e2e ``` ## Variables | 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. Path can point to a GCS object URI, or a local path. A local path to a zip archive will generate a GCS object using its basename, a folder will be zipped and the GCS object name inferred when not specified. | object({…}) | ✓ | | -| [name](variables.tf#L139) | Name used for cloud function and associated resources. | string | ✓ | | -| [project_id](variables.tf#L154) | Project id used for all resources. | string | ✓ | | -| [region](variables.tf#L159) | Region used for all resources. | string | ✓ | | -| [bucket_config](variables.tf#L17) | Enable and configure auto-created bucket. Set fields to null to use defaults. | object({…}) | | null | -| [build_service_account](variables.tf#L32) | Build service account email. | string | | null | -| [build_worker_pool](variables.tf#L38) | Build worker pool, in projects//locations//workerPools/ format. | string | | null | -| [description](variables.tf#L77) | Optional description. | string | | "Terraform managed." | -| [docker_repository_id](variables.tf#L83) | User managed repository created in Artifact Registry. | string | | null | -| [environment_variables](variables.tf#L89) | Cloud function environment variables. | map(string) | | {} | -| [function_config](variables.tf#L95) | Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout. | object({…}) | | {…} | -| [iam](variables.tf#L115) | IAM bindings for topic in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | -| [ingress_settings](variables.tf#L121) | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . | string | | null | -| [kms_key](variables.tf#L127) | 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_id field that was created with the same KMS crypto key. | string | | null | -| [labels](variables.tf#L133) | Resource labels. | map(string) | | {} | -| [prefix](variables.tf#L144) | Optional prefix used for resource names. | string | | null | -| [secrets](variables.tf#L164) | Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format. | map(object({…})) | | {} | -| [service_account](variables.tf#L176) | Service account email. Unused if service account is auto-created. | string | | null | -| [service_account_create](variables.tf#L182) | Auto-create service account. | bool | | false | -| [trigger_config](variables.tf#L188) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | -| [vpc_connector](variables.tf#L206) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | object({…}) | | null | -| [vpc_connector_config](variables.tf#L216) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null | +| [bucket_name](variables.tf#L27) | 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#L51) | Cloud function source. Path can point to a GCS object URI, or a local path. A local path to a zip archive will generate a GCS object using its basename, a folder will be zipped and the GCS object name inferred when not specified. | object({…}) | ✓ | | +| [name](variables.tf#L148) | Name used for cloud function and associated resources. | string | ✓ | | +| [project_id](variables.tf#L163) | Project id used for all resources. | string | ✓ | | +| [region](variables.tf#L168) | Region used for all resources. | string | ✓ | | +| [bucket_config](variables.tf#L17) | Enable and configure auto-created bucket. Set fields to null to use defaults. | object({…}) | | null | +| [build_environment_variables](variables.tf#L33) | A set of key/value environment variable pairs available during build time. | map(string) | | {} | +| [build_service_account](variables.tf#L39) | Build service account email. | string | | null | +| [build_worker_pool](variables.tf#L45) | Build worker pool, in projects//locations//workerPools/ format. | string | | null | +| [description](variables.tf#L84) | Optional description. | string | | "Terraform managed." | +| [docker_repository_id](variables.tf#L90) | User managed repository created in Artifact Registry. | string | | null | +| [environment_variables](variables.tf#L96) | Cloud function environment variables. | map(string) | | {…} | +| [function_config](variables.tf#L104) | Cloud function configuration. Defaults to using main as entrypoint, 1 instance with 256MiB of memory, and 180 second timeout. | object({…}) | | {…} | +| [iam](variables.tf#L124) | IAM bindings for topic in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [ingress_settings](variables.tf#L130) | Control traffic that reaches the cloud function. Allowed values are ALLOW_ALL, ALLOW_INTERNAL_AND_GCLB and ALLOW_INTERNAL_ONLY . | string | | null | +| [kms_key](variables.tf#L136) | 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_id field that was created with the same KMS crypto key. | string | | null | +| [labels](variables.tf#L142) | Resource labels. | map(string) | | {} | +| [prefix](variables.tf#L153) | Optional prefix used for resource names. | string | | null | +| [secrets](variables.tf#L173) | Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format. | map(object({…})) | | {} | +| [service_account](variables.tf#L185) | Service account email. Unused if service account is auto-created. | string | | null | +| [service_account_create](variables.tf#L191) | Auto-create service account. | bool | | false | +| [trigger_config](variables.tf#L197) | Function trigger configuration. Leave null for HTTP trigger. | object({…}) | | null | +| [vpc_connector](variables.tf#L215) | VPC connector configuration. Set create to 'true' if a new connector needs to be created. | object({…}) | | null | +| [vpc_connector_config](variables.tf#L225) | VPC connector network configuration. Must be provided if new VPC connector is being created. | object({…}) | | null | ## Outputs @@ -322,4 +321,11 @@ module "cf-http" { | [trigger_service_account_iam_email](outputs.tf#L72) | Service account email. | | | [uri](outputs.tf#L80) | Cloud function service uri. | | | [vpc_connector](outputs.tf#L85) | VPC connector resource if created. | | + +## Fixtures + +- [cloudbuild-custom-pool.tf](../../tests/fixtures/cloudbuild-custom-pool.tf) +- [functions-default-sa-iam-grants.tf](../../tests/fixtures/functions-default-sa-iam-grants.tf) +- [pubsub.tf](../../tests/fixtures/pubsub.tf) +- [secret-credentials.tf](../../tests/fixtures/secret-credentials.tf) diff --git a/modules/cloud-function-v2/bundle.tf b/modules/cloud-function-v2/bundle.tf index 43ad5c8ee2..661ece8423 100644 --- a/modules/cloud-function-v2/bundle.tf +++ b/modules/cloud-function-v2/bundle.tf @@ -54,6 +54,7 @@ resource "google_storage_bucket" "bucket" { enabled = true } } + force_destroy = var.bucket_config.force_destroy } # compress bundle in a zip archive if it's a folder diff --git a/modules/cloud-function-v2/main.tf b/modules/cloud-function-v2/main.tf index 0089a89996..f85c84efec 100644 --- a/modules/cloud-function-v2/main.tf +++ b/modules/cloud-function-v2/main.tf @@ -70,7 +70,7 @@ resource "google_cloudfunctions2_function" "function" { worker_pool = var.build_worker_pool runtime = var.function_config.runtime entry_point = var.function_config.entry_point - environment_variables = var.environment_variables + environment_variables = var.build_environment_variables docker_repository = var.docker_repository_id source { storage_source { diff --git a/modules/cloud-function-v2/variables.tf b/modules/cloud-function-v2/variables.tf index d347e24fda..c960aad756 100644 --- a/modules/cloud-function-v2/variables.tf +++ b/modules/cloud-function-v2/variables.tf @@ -17,8 +17,9 @@ variable "bucket_config" { description = "Enable and configure auto-created bucket. Set fields to null to use defaults." type = object({ - location = optional(string) + force_destroy = optional(bool) lifecycle_delete_age_days = optional(number) + location = optional(string) }) default = null } @@ -29,6 +30,12 @@ variable "bucket_name" { nullable = false } +variable "build_environment_variables" { + description = "A set of key/value environment variable pairs available during build time." + type = map(string) + default = {} +} + variable "build_service_account" { description = "Build service account email." type = string @@ -89,7 +96,9 @@ variable "docker_repository_id" { variable "environment_variables" { description = "Cloud function environment variables." type = map(string) - default = {} + default = { + LOG_EXECUTION_ID = "true" + } } variable "function_config" { @@ -165,7 +174,7 @@ variable "secrets" { description = "Secret Manager secrets. Key is the variable name or mountpoint, volume versions are in version:path format." type = map(object({ is_volume = bool - project_id = number + project_id = string secret = string versions = list(string) })) @@ -198,7 +207,7 @@ variable "trigger_config" { })), []) service_account_email = optional(string) service_account_create = optional(bool, false) - retry_policy = optional(string) + retry_policy = optional(string, "RETRY_POLICY_DO_NOT_RETRY") # default to avoid permadiff }) default = null } diff --git a/modules/net-lb-app-ext-regional/README.md b/modules/net-lb-app-ext-regional/README.md index c50055e706..e198feab12 100644 --- a/modules/net-lb-app-ext-regional/README.md +++ b/modules/net-lb-app-ext-regional/README.md @@ -719,21 +719,21 @@ For deploying changes to load balancer configuration please refer to [net-lb-app | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [name](variables.tf#L58) | Load balancer name. | string | ✓ | | -| [project_id](variables.tf#L150) | Project id. | string | ✓ | | -| [region](variables.tf#L168) | Region where the load balancer is created. | string | ✓ | | -| [vpc](variables.tf#L187) | VPC-level configuration. | string | ✓ | | +| [name](variables.tf#L59) | Load balancer name. | string | ✓ | | +| [project_id](variables.tf#L151) | Project id. | string | ✓ | | +| [region](variables.tf#L169) | Region where the load balancer is created. | string | ✓ | | +| [vpc](variables.tf#L188) | VPC-level configuration. | string | ✓ | | | [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string | | null | | [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…})) | | {} | | [description](variables.tf#L23) | Optional description used for resources. | string | | "Terraform managed." | | [group_configs](variables.tf#L29) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | | [health_check_configs](variables-health-check.tf#L19) | Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | map(object({…})) | | {…} | -| [https_proxy_config](variables.tf#L41) | HTTPS proxy connfiguration. | object({…}) | | {} | -| [labels](variables.tf#L52) | Labels set on resources. | map(string) | | {} | -| [neg_configs](variables.tf#L63) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | -| [ports](variables.tf#L144) | Optional ports for HTTP load balancer, valid ports are 80 and 8080. | list(string) | | null | -| [protocol](variables.tf#L155) | Protocol supported by this load balancer. | string | | "HTTP" | -| [ssl_certificates](variables.tf#L173) | SSL target proxy certificates (only if protocol is HTTPS) for existing, custom, and managed certificates. | object({…}) | | {} | +| [https_proxy_config](variables.tf#L41) | HTTPS proxy connfiguration. | object({…}) | | {} | +| [labels](variables.tf#L53) | Labels set on resources. | map(string) | | {} | +| [neg_configs](variables.tf#L64) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | +| [ports](variables.tf#L145) | Optional ports for HTTP load balancer, valid ports are 80 and 8080. | list(string) | | null | +| [protocol](variables.tf#L156) | Protocol supported by this load balancer. | string | | "HTTP" | +| [ssl_certificates](variables.tf#L174) | SSL target proxy certificates (only if protocol is HTTPS) for existing, custom, and managed certificates. | object({…}) | | {} | | [urlmap_config](variables-urlmap.tf#L19) | The URL map configuration. | object({…}) | | {…} | ## Outputs diff --git a/modules/net-lb-app-ext-regional/main.tf b/modules/net-lb-app-ext-regional/main.tf index 2ed202b388..edd486c178 100644 --- a/modules/net-lb-app-ext-regional/main.tf +++ b/modules/net-lb-app-ext-regional/main.tf @@ -74,14 +74,13 @@ resource "google_compute_region_target_http_proxy" "default" { } resource "google_compute_region_target_https_proxy" "default" { - count = var.protocol == "HTTPS" ? 1 : 0 - project = var.project_id - name = var.name - region = var.region - description = var.description - # certificate_map = var.https_proxy_config.certificate_map - # quic_override = var.https_proxy_config.quic_override - ssl_certificates = local.proxy_ssl_certificates - ssl_policy = var.https_proxy_config.ssl_policy - url_map = google_compute_region_url_map.default.id + count = var.protocol == "HTTPS" ? 1 : 0 + project = var.project_id + name = var.name + region = var.region + description = var.description + certificate_manager_certificates = var.https_proxy_config.certificate_manager_certificates + ssl_certificates = local.proxy_ssl_certificates + ssl_policy = var.https_proxy_config.ssl_policy + url_map = google_compute_region_url_map.default.id } diff --git a/modules/net-lb-app-ext-regional/variables.tf b/modules/net-lb-app-ext-regional/variables.tf index 85a0034033..fc95274686 100644 --- a/modules/net-lb-app-ext-regional/variables.tf +++ b/modules/net-lb-app-ext-regional/variables.tf @@ -41,9 +41,10 @@ variable "group_configs" { variable "https_proxy_config" { description = "HTTPS proxy connfiguration." type = object({ - certificate_map = optional(string) - quic_override = optional(string) - ssl_policy = optional(string) + certificate_manager_certificates = optional(list(string)) + certificate_map = optional(string) + quic_override = optional(string) + ssl_policy = optional(string) }) default = {} nullable = false diff --git a/modules/net-lb-app-ext/README.md b/modules/net-lb-app-ext/README.md index cb22c26296..eb81460cf7 100644 --- a/modules/net-lb-app-ext/README.md +++ b/modules/net-lb-app-ext/README.md @@ -1017,22 +1017,22 @@ After provisioning this change, and verifying that the new certificate is provis | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [name](variables.tf#L92) | Load balancer name. | string | ✓ | | -| [project_id](variables.tf#L194) | Project id. | string | ✓ | | +| [name](variables.tf#L93) | Load balancer name. | string | ✓ | | +| [project_id](variables.tf#L195) | Project id. | string | ✓ | | | [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string | | null | | [backend_buckets_config](variables.tf#L23) | Backend buckets configuration. | map(object({…})) | | {} | | [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…})) | | {} | | [description](variables.tf#L56) | Optional description used for resources. | string | | "Terraform managed." | | [group_configs](variables.tf#L62) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | | [health_check_configs](variables-health-check.tf#L19) | Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | map(object({…})) | | {…} | -| [https_proxy_config](variables.tf#L74) | HTTPS proxy connfiguration. | object({…}) | | {} | -| [labels](variables.tf#L86) | Labels set on resources. | map(string) | | {} | -| [neg_configs](variables.tf#L97) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | -| [ports](variables.tf#L188) | Optional ports for HTTP load balancer, valid ports are 80 and 8080. | list(string) | | null | -| [protocol](variables.tf#L199) | Protocol supported by this load balancer. | string | | "HTTP" | -| [ssl_certificates](variables.tf#L212) | SSL target proxy certificates (only if protocol is HTTPS) for existing, custom, and managed certificates. | object({…}) | | {} | +| [https_proxy_config](variables.tf#L74) | HTTPS proxy connfiguration. | object({…}) | | {} | +| [labels](variables.tf#L87) | Labels set on resources. | map(string) | | {} | +| [neg_configs](variables.tf#L98) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | +| [ports](variables.tf#L189) | Optional ports for HTTP load balancer, valid ports are 80 and 8080. | list(string) | | null | +| [protocol](variables.tf#L200) | Protocol supported by this load balancer. | string | | "HTTP" | +| [ssl_certificates](variables.tf#L213) | SSL target proxy certificates (only if protocol is HTTPS) for existing, custom, and managed certificates. | object({…}) | | {} | | [urlmap_config](variables-urlmap.tf#L19) | The URL map configuration. | object({…}) | | {…} | -| [use_classic_version](variables.tf#L229) | Use classic Global Load Balancer. | bool | | true | +| [use_classic_version](variables.tf#L230) | Use classic Global Load Balancer. | bool | | true | ## Outputs diff --git a/modules/net-lb-app-ext/main.tf b/modules/net-lb-app-ext/main.tf index f27e786dab..f2680d9886 100644 --- a/modules/net-lb-app-ext/main.tf +++ b/modules/net-lb-app-ext/main.tf @@ -76,14 +76,15 @@ resource "google_compute_target_http_proxy" "default" { } resource "google_compute_target_https_proxy" "default" { - count = var.protocol == "HTTPS" ? 1 : 0 - project = var.project_id - name = var.name - description = var.description - certificate_map = var.https_proxy_config.certificate_map - quic_override = var.https_proxy_config.quic_override - ssl_certificates = local.proxy_ssl_certificates - ssl_policy = var.https_proxy_config.ssl_policy - url_map = google_compute_url_map.default.id - server_tls_policy = var.https_proxy_config.mtls_policy + count = var.protocol == "HTTPS" ? 1 : 0 + project = var.project_id + name = var.name + description = var.description + certificate_map = var.https_proxy_config.certificate_map + certificate_manager_certificates = var.https_proxy_config.certificate_manager_certificates + quic_override = var.https_proxy_config.quic_override + ssl_certificates = local.proxy_ssl_certificates + ssl_policy = var.https_proxy_config.ssl_policy + url_map = google_compute_url_map.default.id + server_tls_policy = var.https_proxy_config.mtls_policy } diff --git a/modules/net-lb-app-ext/variables.tf b/modules/net-lb-app-ext/variables.tf index 2b327c8cf6..a7528881d7 100644 --- a/modules/net-lb-app-ext/variables.tf +++ b/modules/net-lb-app-ext/variables.tf @@ -74,10 +74,11 @@ variable "group_configs" { variable "https_proxy_config" { description = "HTTPS proxy connfiguration." type = object({ - certificate_map = optional(string) - quic_override = optional(string) - ssl_policy = optional(string) - mtls_policy = optional(string) # id of the mTLS policy to use for the target proxy. + certificate_manager_certificates = optional(list(string)) + certificate_map = optional(string) + quic_override = optional(string) + ssl_policy = optional(string) + mtls_policy = optional(string) # id of the mTLS policy to use for the target proxy. }) default = {} nullable = false diff --git a/modules/net-lb-app-int/README.md b/modules/net-lb-app-int/README.md index 0d03472edf..46172cdd22 100644 --- a/modules/net-lb-app-int/README.md +++ b/modules/net-lb-app-int/README.md @@ -738,25 +738,25 @@ For deploying changes to load balancer configuration please refer to [net-lb-app | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [name](variables.tf#L63) | Load balancer name. | string | ✓ | | -| [project_id](variables.tf#L159) | Project id. | string | ✓ | | -| [region](variables.tf#L177) | The region where to allocate the ILB resources. | string | ✓ | | -| [vpc_config](variables.tf#L219) | VPC-level configuration. | object({…}) | ✓ | | +| [name](variables.tf#L64) | Load balancer name. | string | ✓ | | +| [project_id](variables.tf#L160) | Project id. | string | ✓ | | +| [region](variables.tf#L178) | The region where to allocate the ILB resources. | string | ✓ | | +| [vpc_config](variables.tf#L220) | VPC-level configuration. | object({…}) | ✓ | | | [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string | | null | | [backend_service_configs](variables-backend-service.tf#L19) | Backend service level configuration. | map(object({…})) | | {} | | [description](variables.tf#L23) | Optional description used for resources. | string | | "Terraform managed." | | [global_access](variables.tf#L30) | Allow client access from all regions. | bool | | null | | [group_configs](variables.tf#L36) | Optional unmanaged groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | | [health_check_configs](variables-health-check.tf#L19) | Optional auto-created health check configurations, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | map(object({…})) | | {…} | -| [https_proxy_config](variables.tf#L48) | HTTPS proxy configuration. | object({…}) | | {} | -| [labels](variables.tf#L57) | Labels set on resources. | map(string) | | {} | -| [neg_configs](variables.tf#L68) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | -| [network_tier_premium](variables.tf#L146) | Use premium network tier. Defaults to true. | bool | | true | -| [ports](variables.tf#L153) | Optional ports for HTTP load balancer, valid ports are 80 and 8080. | list(string) | | null | -| [protocol](variables.tf#L164) | Protocol supported by this load balancer. | string | | "HTTP" | -| [service_attachment](variables.tf#L182) | PSC service attachment. | object({…}) | | null | -| [service_directory_registration](variables.tf#L197) | Service directory namespace and service used to register this load balancer. | object({…}) | | null | -| [ssl_certificates](variables.tf#L206) | SSL target proxy certificates (only if protocol is HTTPS). | object({…}) | | {} | +| [https_proxy_config](variables.tf#L48) | HTTPS proxy configuration. | object({…}) | | {} | +| [labels](variables.tf#L58) | Labels set on resources. | map(string) | | {} | +| [neg_configs](variables.tf#L69) | Optional network endpoint groups to create. Can be referenced in backends via key or outputs. | map(object({…})) | | {} | +| [network_tier_premium](variables.tf#L147) | Use premium network tier. Defaults to true. | bool | | true | +| [ports](variables.tf#L154) | Optional ports for HTTP load balancer, valid ports are 80 and 8080. | list(string) | | null | +| [protocol](variables.tf#L165) | Protocol supported by this load balancer. | string | | "HTTP" | +| [service_attachment](variables.tf#L183) | PSC service attachment. | object({…}) | | null | +| [service_directory_registration](variables.tf#L198) | Service directory namespace and service used to register this load balancer. | object({…}) | | null | +| [ssl_certificates](variables.tf#L207) | SSL target proxy certificates (only if protocol is HTTPS). | object({…}) | | {} | | [urlmap_config](variables-urlmap.tf#L19) | The URL map configuration. | object({…}) | | {…} | ## Outputs diff --git a/modules/net-lb-app-int/main.tf b/modules/net-lb-app-int/main.tf index 33ea830ea1..d056e8be70 100644 --- a/modules/net-lb-app-int/main.tf +++ b/modules/net-lb-app-int/main.tf @@ -108,14 +108,15 @@ resource "google_compute_region_target_http_proxy" "default" { } resource "google_compute_region_target_https_proxy" "default" { - count = var.protocol == "HTTPS" ? 1 : 0 - project = var.project_id - region = var.region - name = var.name - description = var.description - ssl_certificates = local.proxy_ssl_certificates - ssl_policy = var.https_proxy_config.ssl_policy - url_map = google_compute_region_url_map.default.id + count = var.protocol == "HTTPS" ? 1 : 0 + project = var.project_id + region = var.region + name = var.name + description = var.description + ssl_certificates = local.proxy_ssl_certificates + ssl_policy = var.https_proxy_config.ssl_policy + url_map = google_compute_region_url_map.default.id + certificate_manager_certificates = var.https_proxy_config.certificate_manager_certificates } resource "google_compute_service_attachment" "default" { diff --git a/modules/net-lb-app-int/variables.tf b/modules/net-lb-app-int/variables.tf index a28e658c59..d3311fbe35 100644 --- a/modules/net-lb-app-int/variables.tf +++ b/modules/net-lb-app-int/variables.tf @@ -48,7 +48,8 @@ variable "group_configs" { variable "https_proxy_config" { description = "HTTPS proxy configuration." type = object({ - ssl_policy = optional(string) + certificate_manager_certificates = optional(list(string)) + ssl_policy = optional(string) }) default = {} nullable = false diff --git a/tests/examples_e2e/setup_module/main.tf b/tests/examples_e2e/setup_module/main.tf index f27b90e523..b1e6005ee2 100644 --- a/tests/examples_e2e/setup_module/main.tf +++ b/tests/examples_e2e/setup_module/main.tf @@ -22,8 +22,10 @@ locals { services = [ # trimmed down list of services, to be extended as needed "alloydb.googleapis.com", - "assuredworkloads.googleapis.com", + "analyticshub.googleapis.com", "apigee.googleapis.com", + "artifactregistry.googleapis.com", + "assuredworkloads.googleapis.com", "bigquery.googleapis.com", "cloudbuild.googleapis.com", "cloudfunctions.googleapis.com", @@ -31,10 +33,16 @@ locals { "cloudresourcemanager.googleapis.com", "compute.googleapis.com", "container.googleapis.com", + "dataform.googleapis.com", + "dataplex.googleapis.com", "dataproc.googleapis.com", "dns.googleapis.com", "eventarc.googleapis.com", "iam.googleapis.com", + "logging.googleapis.com", + "monitoring.googleapis.com", + "networkconnectivity.googleapis.com", + "pubsub.googleapis.com", "run.googleapis.com", "secretmanager.googleapis.com", "servicenetworking.googleapis.com", diff --git a/tests/fixtures/cloudbuild-custom-pool.tf b/tests/fixtures/cloudbuild-custom-pool.tf new file mode 100644 index 0000000000..2ee762f091 --- /dev/null +++ b/tests/fixtures/cloudbuild-custom-pool.tf @@ -0,0 +1,26 @@ +/** + * 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. + */ + +resource "google_cloudbuild_worker_pool" "pool" { + project = var.project_id + name = "custom-pool" + location = var.regions.secondary + worker_config { + disk_size_gb = 100 + machine_type = "e2-standard-4" + no_external_ip = false + } +} diff --git a/tests/fixtures/functions-default-sa-iam-grants.tf b/tests/fixtures/functions-default-sa-iam-grants.tf new file mode 100644 index 0000000000..784a5ef264 --- /dev/null +++ b/tests/fixtures/functions-default-sa-iam-grants.tf @@ -0,0 +1,34 @@ +/** + * 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. + */ + +resource "google_project_iam_member" "bucket_default_compute_account_grant" { + project = var.project_id + member = "serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com" + role = "roles/storage.objectViewer" + depends_on = [google_project_iam_member.artifact_writer] +} + +resource "google_project_iam_member" "debugging_grant" { + project = var.project_id + member = "serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com" + role = "roles/logging.logWriter" +} + +resource "google_project_iam_member" "artifact_writer" { + project = var.project_id + member = "serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com" + role = "roles/artifactregistry.createOnPushWriter" +} diff --git a/tests/fixtures/secret-credentials.tf b/tests/fixtures/secret-credentials.tf index 2207e6a29b..7e584041a4 100644 --- a/tests/fixtures/secret-credentials.tf +++ b/tests/fixtures/secret-credentials.tf @@ -22,7 +22,10 @@ module "secret-manager" { } iam = { credentials = { - "roles/secretmanager.secretAccessor" = ["serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com"] + "roles/secretmanager.secretAccessor" = [ + "serviceAccount:${var.project_number}-compute@developer.gserviceaccount.com", + "serviceAccount:${var.project_id}@appspot.gserviceaccount.com", + ] } } versions = { diff --git a/tests/modules/cloud_function_v1/examples/bucket-creation.yaml b/tests/modules/cloud_function_v1/examples/bucket-creation.yaml index b864f908c9..9d08d9ae60 100644 --- a/tests/modules/cloud_function_v1/examples/bucket-creation.yaml +++ b/tests/modules/cloud_function_v1/examples/bucket-creation.yaml @@ -14,9 +14,9 @@ values: module.cf-http.google_cloudfunctions_function.function: - name: my-prefix-test-cf-http - project: my-project - source_archive_bucket: my-prefix-test-cf-bundles + name: test-test-cf-http + project: project-id + source_archive_bucket: test-bucket module.cf-http.google_storage_bucket.bucket[0]: lifecycle_rule: @@ -24,13 +24,13 @@ values: - type: Delete condition: - age: 1 - name: my-prefix-test-cf-bundles + name: test-bucket counts: google_cloudfunctions_function: 1 google_storage_bucket: 1 google_storage_bucket_object: 1 modules: 1 - resources: 3 + resources: 6 -outputs: {} \ No newline at end of file +outputs: {} diff --git a/tests/modules/cloud_function_v1/examples/iam.yaml b/tests/modules/cloud_function_v1/examples/iam.yaml index 363f970b6a..8473e6f3d1 100644 --- a/tests/modules/cloud_function_v1/examples/iam.yaml +++ b/tests/modules/cloud_function_v1/examples/iam.yaml @@ -17,12 +17,12 @@ values: condition: [] members: - allUsers - project: my-project - region: europe-west1 + project: project-id + region: europe-west9 role: roles/cloudfunctions.invoker counts: google_cloudfunctions_function: 1 google_storage_bucket_object: 1 modules: 1 - resources: 3 + resources: 6 diff --git a/tests/modules/cloud_function_v1/examples/multiple_functions.yaml b/tests/modules/cloud_function_v1/examples/multiple_functions.yaml index 2fa803f7db..f550b2c754 100644 --- a/tests/modules/cloud_function_v1/examples/multiple_functions.yaml +++ b/tests/modules/cloud_function_v1/examples/multiple_functions.yaml @@ -14,12 +14,12 @@ values: module.cf-http-one.google_storage_bucket_object.bundle[0]: - source: /tmp/bundle-my-project-test-cf-http-one.zip + source: /tmp/bundle-project-id-test-cf-http-one.zip module.cf-http-two.google_storage_bucket_object.bundle[0]: - source: /tmp/bundle-my-project-test-cf-http-two.zip + source: /tmp/bundle-project-id-test-cf-http-two.zip counts: google_cloudfunctions_function: 2 google_storage_bucket_object: 2 modules: 2 - resources: 4 + resources: 7 diff --git a/tests/modules/cloud_function_v1/examples/secrets.yaml b/tests/modules/cloud_function_v1/examples/secrets.yaml index 47447a62fd..dc5d432bd2 100644 --- a/tests/modules/cloud_function_v1/examples/secrets.yaml +++ b/tests/modules/cloud_function_v1/examples/secrets.yaml @@ -16,24 +16,19 @@ values: module.cf-http.google_cloudfunctions_function.function: secret_environment_variables: - key: VARIABLE_SECRET - project_id: '1234567890' - secret: var_secret + project_id: "123" # actually, project number + # secret: var_secret # known after apply version: latest secret_volumes: - mount_path: /app/secret - project_id: '1234567890' - secret: path_secret + project_id: "123" # actually, project number + # secret: path_secret # known after apply versions: - - path: first - version: '1' - - path: second - version: '2' - - path: latest - version: latest + - {} counts: google_cloudfunctions_function: 1 google_storage_bucket_object: 1 - modules: 1 - resources: 2 + modules: 2 + resources: 8 diff --git a/tests/modules/cloud_function_v2/assets/sample-function/main.py b/tests/modules/cloud_function_v2/assets/sample-function/main.py new file mode 100644 index 0000000000..0e09377c1f --- /dev/null +++ b/tests/modules/cloud_function_v2/assets/sample-function/main.py @@ -0,0 +1,20 @@ +# Copyright 2023 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. + +import functions_framework + + +@functions_framework.http +def main(request): + return "Hello World!" diff --git a/tests/modules/cloud_function_v2/examples/bucket-creation.yaml b/tests/modules/cloud_function_v2/examples/bucket-creation.yaml index abaaf32afc..1e74e9575c 100644 --- a/tests/modules/cloud_function_v2/examples/bucket-creation.yaml +++ b/tests/modules/cloud_function_v2/examples/bucket-creation.yaml @@ -17,17 +17,17 @@ values: build_config: - source: - storage_source: - - bucket: my-prefix-test-cf-bundles - name: my-prefix-test-cf-http - project: my-project + - bucket: test-bucket + name: test-test-cf-http + project: project-id module.cf-http.google_storage_bucket.bucket[0]: lifecycle_rule: - action: - type: Delete condition: - age: 1 - name: my-prefix-test-cf-bundles - project: my-project + name: test-bucket + project: project-id versioning: - enabled: true @@ -36,6 +36,6 @@ counts: google_storage_bucket: 1 google_storage_bucket_object: 1 modules: 1 - resources: 3 + resources: 6 -outputs: {} \ No newline at end of file +outputs: {} diff --git a/tests/modules/cloud_function_v2/examples/iam.yaml b/tests/modules/cloud_function_v2/examples/iam.yaml index 08dc5c430d..2720c26783 100644 --- a/tests/modules/cloud_function_v2/examples/iam.yaml +++ b/tests/modules/cloud_function_v2/examples/iam.yaml @@ -18,22 +18,20 @@ values: location: europe-west8 members: - allUsers - project: my-project + project: project-id role: roles/run.invoker service: test-cf-http module.cf-http.google_cloudfunctions2_function.function: {} module.cf-http.google_storage_bucket_object.bundle[0]: - bucket: test-cf-bundles + bucket: bucket customer_encryption: [] detect_md5hash: different hash - name: bundle-6f1ece136848fee658e335b05fe2d79d.zip - source: /tmp/bundle-my-project-test-cf-http.zip + name: bundle-95c1b0e5b92dae8333539b1e0ad5173b.zip + source: /tmp/bundle-project-id-test-cf-http.zip counts: google_cloud_run_service_iam_binding: 1 google_cloudfunctions2_function: 1 google_storage_bucket_object: 1 modules: 1 - resources: 3 - - + resources: 6 diff --git a/tests/modules/cloud_function_v2/examples/multiple_functions.yaml b/tests/modules/cloud_function_v2/examples/multiple_functions.yaml index e7cf10d540..65b7a18b9b 100644 --- a/tests/modules/cloud_function_v2/examples/multiple_functions.yaml +++ b/tests/modules/cloud_function_v2/examples/multiple_functions.yaml @@ -14,12 +14,12 @@ values: module.cf-http-one.google_storage_bucket_object.bundle[0]: - source: /tmp/bundle-my-project-test-cf-http-one.zip + source: /tmp/bundle-project-id-test-cf-http-one.zip module.cf-http-two.google_storage_bucket_object.bundle[0]: - source: /tmp/bundle-my-project-test-cf-http-two.zip + source: /tmp/bundle-project-id-test-cf-http-two.zip counts: google_cloudfunctions2_function: 2 google_storage_bucket_object: 2 modules: 2 - resources: 4 + resources: 7 diff --git a/tests/modules/cloud_function_v2/examples/secrets.yaml b/tests/modules/cloud_function_v2/examples/secrets.yaml index 1dccd340aa..77a36c8c63 100644 --- a/tests/modules/cloud_function_v2/examples/secrets.yaml +++ b/tests/modules/cloud_function_v2/examples/secrets.yaml @@ -18,24 +18,18 @@ values: service_config: - secret_environment_variables: - key: VARIABLE_SECRET - project_id: '1234567890' - secret: var_secret + project_id: project-id + # secret: var_secret # known after apply version: latest secret_volumes: - mount_path: /app/secret - project_id: '1234567890' - secret: path_secret + project_id: project-id + # secret: var_secret # known after apply versions: - - path: first - version: '1' - - path: second - version: '2' - - path: latest - version: latest + - {} counts: google_cloudfunctions2_function: 1 google_storage_bucket_object: 1 - modules: 1 - resources: 2 - + modules: 2 + resources: 8 diff --git a/tools/create_e2e_sandbox.sh b/tools/create_e2e_sandbox.sh index 206a274a74..9ce75b96b0 100755 --- a/tools/create_e2e_sandbox.sh +++ b/tools/create_e2e_sandbox.sh @@ -28,7 +28,7 @@ # set -e -DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && cd .. && pwd ) +DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && cd .. && pwd) DEST=$1 INFRA="${DEST}/infra" TIMESTAMP=$(date +%s) @@ -42,18 +42,18 @@ cp "${SETUP_MODULE}/main.tf" "${SETUP_MODULE}/variables.tf" "${SETUP_MODULE}/e2e cp "${DIR}/tests/examples/variables.tf" "${DEST}" -if [ ! -f "${INFRA}/randomizer.auto.tfvars" ] ; then - echo "suffix=0" > "${INFRA}/randomizer.auto.tfvars" - echo "timestamp=${TIMESTAMP}" >> "${INFRA}/randomizer.auto.tfvars" +if [ ! -f "${INFRA}/randomizer.auto.tfvars" ]; then + echo "suffix=0" >"${INFRA}/randomizer.auto.tfvars" + echo "timestamp=${TIMESTAMP}" >>"${INFRA}/randomizer.auto.tfvars" fi # TODO correct environment variable prefix -export | sed -e 's/^declare -x //' | grep '^TFTEST_E2E_' | sed -e 's/^TFTEST_E2E_//' > "${INFRA}/terraform.tfvars" +export | sed -e 's/^declare -x //' | grep '^TFTEST_E2E_' | sed -e 's/^TFTEST_E2E_//' >"${INFRA}/terraform.tfvars" ( - cd "${INFRA}" - terraform init - terraform apply -auto-approve - ln -sfT "${INFRA}/e2e_tests.tfvars" "${DEST}/e2e_tests.auto.tfvars" + cd "${INFRA}" + terraform init + terraform apply -auto-approve + ln -sfT "${INFRA}/e2e_tests.tfvars" "${DEST}/e2e_tests.auto.tfvars" ) -tocuh "${DEST}/main.tf" +touch "${DEST}/main.tf"