diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index a73d8ae202..b8e21a37ab 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -25,15 +25,17 @@ jobs: linting: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: "3.10" + cache: 'pip' + cache-dependency-path: 'tools/requirements.txt' - name: Set up Terraform - uses: hashicorp/setup-terraform@v1 + uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.3.2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 494aa6b5dd..55e3f58e6e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -34,7 +34,7 @@ jobs: name: "Release new version" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Validate input" run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3e452275b0..760f866841 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -28,13 +28,13 @@ env: PYTEST_ADDOPTS: "--color=yes" PYTHON_VERSION: "3.10" TF_PLUGIN_CACHE_DIR: "/home/runner/.terraform.d/plugin-cache" - TF_VERSION: 1.3.2 + TF_VERSION: 1.3.9 jobs: examples: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Config auth run: | @@ -42,9 +42,11 @@ jobs: | tee -a $GOOGLE_APPLICATION_CREDENTIALS - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + cache-dependency-path: 'tests/requirements.txt' - name: Set up Terraform uses: hashicorp/setup-terraform@v2 @@ -69,7 +71,7 @@ jobs: blueprints: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Config auth run: | @@ -77,9 +79,11 @@ jobs: | tee -a $GOOGLE_APPLICATION_CREDENTIALS - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + cache-dependency-path: 'tests/requirements.txt' - name: Set up Terraform uses: hashicorp/setup-terraform@v2 @@ -104,7 +108,7 @@ jobs: modules: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Config auth run: | @@ -112,9 +116,11 @@ jobs: | tee -a $GOOGLE_APPLICATION_CREDENTIALS - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + cache-dependency-path: 'tests/requirements.txt' - name: Set up Terraform uses: hashicorp/setup-terraform@v2 @@ -139,7 +145,7 @@ jobs: fast: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Config auth run: | @@ -147,9 +153,11 @@ jobs: | tee -a $GOOGLE_APPLICATION_CREDENTIALS - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} + cache: 'pip' + cache-dependency-path: 'tests/requirements.txt' - name: Set up Terraform uses: hashicorp/setup-terraform@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d6ab82950..6b327ac9a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,20 +6,78 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### BLUEPRINTS + +- [[#1184](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1184)] **incompatible change:** Allow multiple peer gateways in VPN HA module ([ludoo](https://github.com/ludoo)) +- [[#1143](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1143)] Test blueprints from README files ([juliocc](https://github.com/juliocc)) +- [[#1181](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1181)] Bump golang.org/x/sys from 0.0.0-20220310020820-b874c991c1a5 to 0.1.0 in /blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker ([dependabot[bot]](https://github.com/dependabot[bot])) +- [[#1180](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1180)] Bump golang.org/x/sys from 0.0.0-20220310020820-b874c991c1a5 to 0.1.0 in /blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter ([dependabot[bot]](https://github.com/dependabot[bot])) +- [[#1175](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1175)] Serverless networking program ([juliodiez](https://github.com/juliodiez)) +- [[#1179](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1179)] Added a PSC GCLB example ([cgrotz](https://github.com/cgrotz)) +- [[#1165](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1165)] DataPlatform: Support project creation ([lcaggio](https://github.com/lcaggio)) +- [[#1167](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1167)] **incompatible change:** Simplify org policies in resource management modules ([juliocc](https://github.com/juliocc)) +- [[#1161](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1161)] Additional documentation for the Data Platform Dataflow pipeline example ([aymanfarhat](https://github.com/aymanfarhat)) +- [[#1154](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1154)] Workaround to mitigate provider issue 9164 ([lcaggio](https://github.com/lcaggio)) +- [[#1146](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1146)] Serverless networking program ([juliodiez](https://github.com/juliodiez)) +- [[#1142](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1142)] Fix bq factory docs ([juliocc](https://github.com/juliocc)) +- [[#1138](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1138)] New compute-vm examples and tests ([juliocc](https://github.com/juliocc)) +- [[#1132](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1132)] Add descriptive name as optional argument ([paulwoelfel](https://github.com/paulwoelfel)) +- [[#1105](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1105)] [Feature] Update data platform blue print with Dataflow Flex template ([aymanfarhat](https://github.com/aymanfarhat)) +- [[#1129](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1129)] Update KMS blueprint ([lcaggio](https://github.com/lcaggio)) + ### DOCUMENTATION +- [[#1179](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1179)] Added a PSC GCLB example ([cgrotz](https://github.com/cgrotz)) +- [[#1165](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1165)] DataPlatform: Support project creation ([lcaggio](https://github.com/lcaggio)) +- [[#1145](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1145)] FAST stage docs cleanup ([ludoo](https://github.com/ludoo)) +- [[#1137](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1137)] **incompatible change:** Allow configuring regions from tfvars in FAST networking stages ([ludoo](https://github.com/ludoo)) +- [[#1105](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1105)] [Feature] Update data platform blue print with Dataflow Flex template ([aymanfarhat](https://github.com/aymanfarhat)) - [[#1052](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1052)] **incompatible change:** FAST multitenant bootstrap and resource management, rename org-level FAST stages ([ludoo](https://github.com/ludoo)) ### FAST +- [[#1184](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1184)] **incompatible change:** Allow multiple peer gateways in VPN HA module ([ludoo](https://github.com/ludoo)) +- [[#1165](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1165)] DataPlatform: Support project creation ([lcaggio](https://github.com/lcaggio)) +- [[#1170](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1170)] Add documentation about referring modules stored on CSR ([wiktorn](https://github.com/wiktorn)) +- [[#1167](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1167)] **incompatible change:** Simplify org policies in resource management modules ([juliocc](https://github.com/juliocc)) +- [[#1164](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1164)] fix module_prefix in fast extras 0-cicd-github ([antonkovach](https://github.com/antonkovach)) +- [[#1162](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1162)] Fix Terraform formatting and add module_prefix attribute to modules_config ([antonkovach](https://github.com/antonkovach)) +- [[#1145](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1145)] FAST stage docs cleanup ([ludoo](https://github.com/ludoo)) +- [[#1137](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1137)] **incompatible change:** Allow configuring regions from tfvars in FAST networking stages ([ludoo](https://github.com/ludoo)) +- [[#1133](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1133)] Align VPN peer interface to module in FAST net VPN stage ([simonebruzzechesse](https://github.com/simonebruzzechesse)) +- [[#1135](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1135)] Post PR message in GitHub workflow on init or validate failure ([ludoo](https://github.com/ludoo)) +- [[#1134](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1134)] Fix stage 1 output file names and stage links script ([ludoo](https://github.com/ludoo)) +- [[#1128](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1128)] Remove info about non-existing vpc-peering-*.tf files ([skalolazka](https://github.com/skalolazka)) - [[#1052](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1052)] **incompatible change:** FAST multitenant bootstrap and resource management, rename org-level FAST stages ([ludoo](https://github.com/ludoo)) ### MODULES +- [[#1184](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1184)] **incompatible change:** Allow multiple peer gateways in VPN HA module ([ludoo](https://github.com/ludoo)) +- [[#1177](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1177)] Implemented conditional dynamic blocks for `google_access_context_manager_service_perimeter` `spec` and `status` ([calexandre](https://github.com/calexandre)) +- [[#1178](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1178)] adding meshconfig.googleapis.com to JIT list. ([valeriobponza](https://github.com/valeriobponza)) +- [[#1174](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1174)] Don't define nor use health checks with SNEGs ([juliodiez](https://github.com/juliodiez)) +- [[#1172](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1172)] Allow to not use any health check ([juliodiez](https://github.com/juliodiez)) +- [[#1171](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1171)] Modifications related to autopilot and workload identity. Added workl… ([apichick](https://github.com/apichick)) +- [[#1167](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1167)] **incompatible change:** Simplify org policies in resource management modules ([juliocc](https://github.com/juliocc)) +- [[#1168](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1168)] Remove unused attribute from project module README example ([juliodiez](https://github.com/juliodiez)) +- [[#1166](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1166)] Fix variable name in VPC-SC module examples ([juliodiez](https://github.com/juliodiez)) +- [[#1153](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1153)] net-vpc - add missing iam properties to factory_subnets ([jamesdalf](https://github.com/jamesdalf)) +- [[#1163](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1163)] Projects-data-source module new version ([averbuks](https://github.com/averbuks)) +- [[#1160](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1160)] Allow additive IAM grants by robots name ([wiktorn](https://github.com/wiktorn)) +- [[#1158](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1158)] changed pod_range reference to include secondary_pod_range issue #1157 ([chemapolo](https://github.com/chemapolo)) +- [[#1156](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1156)] Add 'max_time_travel_hours ' support on BQ module ([lcaggio](https://github.com/lcaggio)) +- [[#1151](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1151)] Add example about referencing existing MIGs to net-ilb module readme ([LucaPrete](https://github.com/LucaPrete)) +- [[#1149](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1149)] Add documentation about JIT-ed service accounts ([wiktorn](https://github.com/wiktorn)) +- [[#1131](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1131)] Add Autopilot Support for cluster_autoscaling Configuration in GKE Module ([tacchino](https://github.com/tacchino)) +- [[#1140](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1140)] CloudSQL Backup Configuration: Support Point In Time Recovery ([tacchino](https://github.com/tacchino)) +- [[#1147](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1147)] Fix gke-cluster dns config feature ([juliocc](https://github.com/juliocc)) +- [[#1144](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1144)] Fixes for service-mesh example in gke-hub ([wiktorn](https://github.com/wiktorn)) +- [[#1138](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1138)] New compute-vm examples and tests ([juliocc](https://github.com/juliocc)) - [[#1052](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1052)] **incompatible change:** FAST multitenant bootstrap and resource management, rename org-level FAST stages ([ludoo](https://github.com/ludoo)) ### TOOLS +- [[#1182](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1182)] Bump actions versions ([juliocc](https://github.com/juliocc)) - [[#1052](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/1052)] **incompatible change:** FAST multitenant bootstrap and resource management, rename org-level FAST stages ([ludoo](https://github.com/ludoo)) ## [20.0.0] - 2023-02-04 diff --git a/README.md b/README.md index 78cddc5cd0..3a499a3712 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Currently available modules: - **foundational** - [billing budget](./modules/billing-budget), [Cloud Identity group](./modules/cloud-identity-group/), [folder](./modules/folder), [service accounts](./modules/iam-service-account), [logging bucket](./modules/logging-bucket), [organization](./modules/organization), [project](./modules/project), [projects-data-source](./modules/projects-data-source) - **networking** - [DNS](./modules/dns), [Cloud Endpoints](./modules/endpoints), [address reservation](./modules/net-address), [NAT](./modules/net-cloudnat), [Global Load Balancer (classic)](./modules/net-glb/), [L4 ILB](./modules/net-ilb), [L7 ILB](./modules/net-ilb-l7), [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN dynamic](./modules/net-vpn-dynamic), [HA VPN](./modules/net-vpn-ha), [VPN static](./modules/net-vpn-static), [Service Directory](./modules/service-directory) - **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool) -- **data** - [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub) +- **data** - [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Cloud SQL instance](./modules/cloudsql-instance), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub) - **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository) - **security** - [Binauthz](./modules/binauthz/), [KMS](./modules/kms), [SecretManager](./modules/secret-manager), [VPC Service Control](./modules/vpc-sc) - **serverless** - [Cloud Function](./modules/cloud-function), [Cloud Run](./modules/cloud-run) diff --git a/blueprints/README.md b/blueprints/README.md index 60a84912dc..b108f86199 100644 --- a/blueprints/README.md +++ b/blueprints/README.md @@ -5,12 +5,12 @@ This section provides **[networking blueprints](./networking/)** that implement Currently available blueprints: - **apigee** - [Apigee Hybrid on GKE](./apigee/hybrid-gke/), [Apigee X analytics in BigQuery](./apigee/bigquery-analytics), [Apigee network patterns](./apigee/network-patterns/) -- **cloud operations** - [Active Directory Federation Services](./cloud-operations/adfs), [Cloud Asset Inventory feeds for resource change tracking and remediation](./cloud-operations/asset-inventory-feed-remediation), [Fine-grained Cloud DNS IAM via Service Directory](./cloud-operations/dns-fine-grained-iam), [Cloud DNS & Shared VPC design](./cloud-operations/dns-shared-vpc), [Delegated Role Grants](./cloud-operations/iam-delegated-role-grants), [Networking Dashboard](./cloud-operations/network-dashboard), [Managing on-prem service account keys by uploading public keys](./cloud-operations/onprem-sa-key-management), [Compute Image builder with Hashicorp Packer](./cloud-operations/packer-image-builder), [Packer example](./cloud-operations/packer-image-builder/packer), [Compute Engine quota monitoring](./cloud-operations/quota-monitoring), [Scheduled Cloud Asset Inventory Export to Bigquery](./cloud-operations/scheduled-asset-inventory-export-bq), [Configuring workload identity federation for Terraform Cloud/Enterprise workflow](./cloud-operations/terraform-enterprise-wif), [TCP healthcheck and restart for unmanaged GCE instances](./cloud-operations/unmanaged-instances-healthcheck), [Migrate for Compute Engine (v5) blueprints](./cloud-operations/vm-migration), [Configuring workload identity federation to access Google Cloud resources from apps running on Azure](./cloud-operations/workload-identity-federation) +- **cloud operations** - [Active Directory Federation Services](./cloud-operations/adfs), [Cloud Asset Inventory feeds for resource change tracking and remediation](./cloud-operations/asset-inventory-feed-remediation), [Fine-grained Cloud DNS IAM via Service Directory](./cloud-operations/dns-fine-grained-iam), [Cloud DNS & Shared VPC design](./cloud-operations/dns-shared-vpc), [Delegated Role Grants](./cloud-operations/iam-delegated-role-grants), [Networking Dashboard](./cloud-operations/network-dashboard), [Managing on-prem service account keys by uploading public keys](./cloud-operations/onprem-sa-key-management), [Compute Image builder with Hashicorp Packer](./cloud-operations/packer-image-builder), [Packer example](./cloud-operations/packer-image-builder/packer), [Compute Engine quota monitoring](./cloud-operations/quota-monitoring), [Scheduled Cloud Asset Inventory Export to Bigquery](./cloud-operations/scheduled-asset-inventory-export-bq), [Configuring workload identity federation with Terraform Cloud/Enterprise workflows](./cloud-operations/terraform-cloud-dynamic-credentials), [TCP healthcheck and restart for unmanaged GCE instances](./cloud-operations/unmanaged-instances-healthcheck), [Migrate for Compute Engine (v5) blueprints](./cloud-operations/vm-migration), [Configuring workload identity federation to access Google Cloud resources from apps running on Azure](./cloud-operations/workload-identity-federation) - **data solutions** - [GCE and GCS CMEK via centralized Cloud KMS](./data-solutions/cmek-via-centralized-kms), [Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key](./data-solutions/composer-2), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion), [Data Platform](./data-solutions/data-platform-foundations), [Spinning up a foundation data pipeline on Google Cloud using Cloud Storage, Dataflow and BigQuery](./data-solutions/gcs-to-bq-with-least-privileges), [#SQL Server Always On Groups blueprint](./data-solutions/sqlserver-alwayson), [Data Playground](./data-solutions/data-playground), [MLOps with Vertex AI](./data-solutions/vertex-mlops), [Shielded Folder](./data-solutions/shielded-folder) - **factories** - [The why and the how of Resource Factories](./factories), [Google Cloud Identity Group Factory](./factories/cloud-identity-group-factory), [Google Cloud BQ Factory](./factories/bigquery-factory), [Google Cloud VPC Firewall Factory](./factories/net-vpc-firewall-yaml), [Minimal Project Factory](./factories/project-factory) - **GKE** - [Binary Authorization Pipeline Blueprint](./gke/binauthz), [Storage API](./gke/binauthz/image), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api), [GKE Multitenant Blueprint](./gke/multitenant-fleet), [Shared VPC with GKE support](./networking/shared-vpc-gke/) - **networking** - [Decentralized firewall management](./networking/decentralized-firewall), [Decentralized firewall validator](./networking/decentralized-firewall/validator), [Network filtering with Squid](./networking/filtering-proxy), [Network filtering with Squid with isolated VPCs using Private Service Connect](./networking/filtering-proxy-psc), [HTTP Load Balancer with Cloud Armor](./networking/glb-and-armor), [Hub and Spoke via VPN](./networking/hub-and-spoke-vpn), [Hub and Spoke via VPC Peering](./networking/hub-and-spoke-peering), [Internal Load Balancer as Next Hop](./networking/ilb-next-hop), On-prem DNS and Google Private Access, [Calling a private Cloud Function from On-premises](./networking/private-cloud-function-from-onprem), [Hybrid connectivity to on-premise services through PSC](./networking/psc-hybrid), [PSC Producer](./networking/psc-hybrid/psc-producer), [PSC Consumer](./networking/psc-hybrid/psc-consumer), [Shared VPC with optional GKE cluster](./networking/shared-vpc-gke) -- **serverless** - [Creating multi-region deployments for API Gateway](./serverless/api-gateway) +- **serverless** - [Creating multi-region deployments for API Gateway](./serverless/api-gateway), [Cloud Run series](./serverless/cloud-run-explore) - **third party solutions** - [OpenShift on GCP user-provisioned infrastructure](./third-party-solutions/openshift), [Wordpress deployment on Cloud Run](./third-party-solutions/wordpress/cloudrun) For more information see the individual README files in each section. diff --git a/blueprints/apigee/bigquery-analytics/README.md b/blueprints/apigee/bigquery-analytics/README.md index 027f28ead8..817c39bb24 100644 --- a/blueprints/apigee/bigquery-analytics/README.md +++ b/blueprints/apigee/bigquery-analytics/README.md @@ -76,3 +76,35 @@ Do the following to verify that everything works as expected. | [ip_address](outputs.tf#L17) | IP address. | | +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/apigee/bigquery-analytics" + project_create = { + billing_account_id = "12345-12345-12345" + parent = "folders/123456789" + } + project_id = "my-project" + envgroups = { + test = ["test.cool-demos.space"] + } + environments = { + apis-test = { + envgroups = ["test"] + } + } + instances = { + instance-ew1 = { + region = "europe-west1" + environments = ["apis-test"] + runtime_ip_cidr_range = "10.0.4.0/22" + troubleshooting_ip_cidr_range = "10.1.0.0/28" + } + } + psc_config = { + europe-west1 = "10.0.0.0/28" + } +} +# tftest modules=10 resources=62 +``` diff --git a/blueprints/apigee/bigquery-analytics/versions.tf b/blueprints/apigee/bigquery-analytics/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/apigee/bigquery-analytics/versions.tf +++ b/blueprints/apigee/bigquery-analytics/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/apigee/hybrid-gke/README.md b/blueprints/apigee/hybrid-gke/README.md index ae5c03648b..05614fac30 100644 --- a/blueprints/apigee/hybrid-gke/README.md +++ b/blueprints/apigee/hybrid-gke/README.md @@ -25,11 +25,11 @@ The diagram below depicts the architecture. terraform apply ``` - Create an A record in your DNS registrar to point the environment group hostname to the public IP address returned after the terraform configuration was applied. You might need to wait some time until the certificate is provisioned. - + Create an A record in your DNS registrar to point the environment group hostname to the public IP address returned after the terraform configuration was applied. You might need to wait some time until the certificate is provisioned. + 5. Install Apigee hybrid using de ansible playbook that is in the ansible folder by running this command - ansible-playbook playbook.yaml -vvvß + ansible-playbook playbook.yaml -vvv ## Testing the blueprint @@ -67,3 +67,18 @@ The diagram below depicts the architecture. | [ip_address](outputs.tf#L17) | GLB IP address. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/apigee/hybrid-gke" + project_create = { + billing_account_id = "12345-12345-12345" + parent = "folders/123456789" + } + project_id = "my-project" + hostname = "test.myorg.org" +} +# tftest modules=18 resources=59 +``` diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md index 690458f03c..0ec240b0f2 100644 --- a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md @@ -67,3 +67,17 @@ Do the following to verify that everything works as expected. | [ip_address](outputs.tf#L17) | GLB IP address. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg" + billing_account_id = "12345-12345-12345" + parent = "folders/123456789" + apigee_project_id = "my-apigee-project" + onprem_project_id = "my-onprem-project" + hostname = "test.myorg.org" +} +# tftest modules=14 resources=73 +``` diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf index c39878d19d..1086f19c6a 100644 --- a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf @@ -32,8 +32,8 @@ module "apigee_vpn" { mode = "CUSTOM" } } - peer_gateway = { - gcp = module.onprem_vpn.self_link + peer_gateways = { + default = { gcp = module.onprem_vpn.self_link } } tunnels = { 0 = { @@ -82,8 +82,8 @@ module "onprem_vpn" { mode = "CUSTOM" } } - peer_gateway = { - gcp = module.apigee_vpn.self_link + peer_gateways = { + default = { gcp = module.apigee_vpn.self_link } } tunnels = { 0 = { diff --git a/blueprints/cloud-operations/README.md b/blueprints/cloud-operations/README.md index 863aee5812..99013624e5 100644 --- a/blueprints/cloud-operations/README.md +++ b/blueprints/cloud-operations/README.md @@ -64,9 +64,9 @@ This [blueprint](./onprem-sa-key-management) shows how to manage IAM Service Acc
-## Workload identity federation for Terraform Enterprise workflow +## Workload identity federation with Terraform Cloud workflows - This [blueprint](./terraform-enterprise-wif) shows how to configure [Wokload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) between [Terraform Cloud/Enterprise](https://developer.hashicorp.com/terraform/enterprise) instance and Google Cloud. + This [blueprint](./terraform-cloud-dynamic-credentials) shows how to configure [Wokload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) between [Terraform Cloud/Enterprise](https://developer.hashicorp.com/terraform/enterprise) instance and Google Cloud.
diff --git a/blueprints/cloud-operations/adfs/README.md b/blueprints/cloud-operations/adfs/README.md index 36b772f8e7..b1efb7b74a 100644 --- a/blueprints/cloud-operations/adfs/README.md +++ b/blueprints/cloud-operations/adfs/README.md @@ -74,3 +74,20 @@ Once done testing, you can clean up resources by running `terraform destroy`. | [ip_address](outputs.tf#L15) | IP address. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/adfs" + prefix = "test" + project_create = { + billing_account_id = "12345-12345-12345" + parent = "folders/123456789" + } + project_id = "project-1" + ad_dns_domain_name = "example.com" + adfs_dns_domain_name = "adfs.example.com" +} +# tftest modules=5 resources=18 +``` diff --git a/blueprints/cloud-operations/adfs/versions.tf b/blueprints/cloud-operations/adfs/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/adfs/versions.tf +++ b/blueprints/cloud-operations/adfs/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/asset-inventory-feed-remediation/README.md b/blueprints/cloud-operations/asset-inventory-feed-remediation/README.md index fdbda73bfc..1025a6be91 100644 --- a/blueprints/cloud-operations/asset-inventory-feed-remediation/README.md +++ b/blueprints/cloud-operations/asset-inventory-feed-remediation/README.md @@ -72,3 +72,15 @@ Run the `subscription_pull` command until it returns nothing, then run the follo | [tag_show](outputs.tf#L49) | Instance add tag command. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/asset-inventory-feed-remediation" + project_create = true + project_id = "project-1" +} + +# tftest modules=7 resources=21 +``` diff --git a/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf b/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf index 6fc1948e99..163fc0f10c 100644 --- a/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf +++ b/blueprints/cloud-operations/asset-inventory-feed-remediation/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -82,7 +82,7 @@ module "cf" { location = var.region } bundle_config = { - source_dir = "cf" + source_dir = "${path.module}/cf" output_path = var.bundle_path } service_account = module.service-account.email diff --git a/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf b/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf +++ b/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/dns-fine-grained-iam/README.md b/blueprints/cloud-operations/dns-fine-grained-iam/README.md index adfc769fa7..8fe402f2c2 100644 --- a/blueprints/cloud-operations/dns-fine-grained-iam/README.md +++ b/blueprints/cloud-operations/dns-fine-grained-iam/README.md @@ -118,3 +118,15 @@ dig app1.svc.example.org +short | [vms](outputs.tf#L25) | VM names. | | + +## Test + +```hcl +module "test1" { + source = "./fabric/blueprints/cloud-operations/dns-fine-grained-iam" + name = "dns-sd-test" + project_create = true + project_id = "test" +} +# tftest modules=9 resources=25 +``` diff --git a/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf b/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf +++ b/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/dns-shared-vpc/README.md b/blueprints/cloud-operations/dns-shared-vpc/README.md index 9dc4c2ea66..6d6e627b9c 100644 --- a/blueprints/cloud-operations/dns-shared-vpc/README.md +++ b/blueprints/cloud-operations/dns-shared-vpc/README.md @@ -39,3 +39,17 @@ Note that Terraform 0.13 at least is required due to the use of `for_each` with | [teams](outputs.tf#L17) | Team resources. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/dns-shared-vpc" + billing_account_id = "111111-222222-333333" + folder_id = "folders/1234567890" + prefix = "test" + shared_vpc_link = "https://www.googleapis.com/compute/v1/projects/test-dns/global/networks/default" + teams = ["team1", "team2"] +} +# tftest modules=9 resources=12 +``` diff --git a/blueprints/cloud-operations/dns-shared-vpc/versions.tf b/blueprints/cloud-operations/dns-shared-vpc/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/dns-shared-vpc/versions.tf +++ b/blueprints/cloud-operations/dns-shared-vpc/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/iam-delegated-role-grants/README.md b/blueprints/cloud-operations/iam-delegated-role-grants/README.md index 4c4d227da6..62a6af7bd8 100644 --- a/blueprints/cloud-operations/iam-delegated-role-grants/README.md +++ b/blueprints/cloud-operations/iam-delegated-role-grants/README.md @@ -76,3 +76,15 @@ If you get any warnings, check the roles and remove any of them granting any of | [restricted_role_grant](variables.tf#L78) | Role grant to which the restrictions will apply. | string | | "roles/resourcemanager.projectIamAdmin" | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/iam-delegated-role-grants" + project_create = true + project_id = "project-1" + project_administrators = ["user:user@example.com"] +} +# tftest modules=2 resources=4 +``` diff --git a/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf b/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf +++ b/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/onprem-sa-key-management/README.md b/blueprints/cloud-operations/onprem-sa-key-management/README.md index 4d6f3ab280..bcbf661e1e 100644 --- a/blueprints/cloud-operations/onprem-sa-key-management/README.md +++ b/blueprints/cloud-operations/onprem-sa-key-management/README.md @@ -78,3 +78,14 @@ terraform destroy -var project_id=$GOOGLE_CLOUD_PROJECT | [sa-credentials](outputs.tf#L17) | SA json key templates. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/onprem-sa-key-management" + project_create = true + project_id = "test" +} +# tftest modules=4 resources=7 +``` diff --git a/blueprints/cloud-operations/onprem-sa-key-management/versions.tf b/blueprints/cloud-operations/onprem-sa-key-management/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/onprem-sa-key-management/versions.tf +++ b/blueprints/cloud-operations/onprem-sa-key-management/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/packer-image-builder/README.md b/blueprints/cloud-operations/packer-image-builder/README.md index 94755e6f22..57dd1ba5f2 100644 --- a/blueprints/cloud-operations/packer-image-builder/README.md +++ b/blueprints/cloud-operations/packer-image-builder/README.md @@ -93,3 +93,27 @@ address for security reasons, Internet connectivity is done with [Cloud NAT](htt | [compute_zone](outputs.tf#L32) | Name of a compute engine zone for Packer's temporary VM. | | + +## Test + +```tpl +# tftest-file id=pkrvars path=packer/build.pkrvars.tpl +# Packer variables file template. +# Used by Terraform to generate Packer variable file. +project_id = "${PROJECT_ID}" +compute_zone = "${COMPUTE_ZONE}" +builder_sa = "${BUILDER_SA}" +compute_sa = "${COMPUTE_SA}" +compute_subnetwork = "${COMPUTE_SUBNETWORK}" +use_iap = ${USE_IAP} +``` + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/packer-image-builder" + project_id = "test-project" + packer_account_users = ["user:john@example.com"] + create_packer_vars = true +} +# tftest modules=7 resources=17 files=pkrvars +``` diff --git a/blueprints/cloud-operations/packer-image-builder/versions.tf b/blueprints/cloud-operations/packer-image-builder/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/packer-image-builder/versions.tf +++ b/blueprints/cloud-operations/packer-image-builder/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/quota-monitoring/README.md b/blueprints/cloud-operations/quota-monitoring/README.md index adcd89d643..571ffb2b02 100644 --- a/blueprints/cloud-operations/quota-monitoring/README.md +++ b/blueprints/cloud-operations/quota-monitoring/README.md @@ -52,3 +52,15 @@ Clone this repository or [open it in cloud shell](https://ssh.cloud.google.com/c | [schedule_config](variables.tf#L66) | Schedule timer configuration in crontab format. | string | | "0 * * * *" | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/quota-monitoring" + name = "name" + project_create = true + project_id = "test" +} +# tftest modules=4 resources=14 +``` diff --git a/blueprints/cloud-operations/quota-monitoring/main.tf b/blueprints/cloud-operations/quota-monitoring/main.tf index fae9af514c..23aaf6f2d0 100644 --- a/blueprints/cloud-operations/quota-monitoring/main.tf +++ b/blueprints/cloud-operations/quota-monitoring/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -55,7 +55,7 @@ module "cf" { location = var.region } bundle_config = { - source_dir = "cf" + source_dir = "${path.module}/cf" output_path = var.bundle_path } # https://github.com/hashicorp/terraform-provider-archive/issues/40 diff --git a/blueprints/cloud-operations/quota-monitoring/versions.tf b/blueprints/cloud-operations/quota-monitoring/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/quota-monitoring/versions.tf +++ b/blueprints/cloud-operations/quota-monitoring/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/README.md b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/README.md index 9e66ba391e..6944cc574c 100644 --- a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/README.md +++ b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/README.md @@ -77,3 +77,29 @@ This is an optional part, created if `cai_gcs_export` is set to `true`. The high | [cloud-function](outputs.tf#L22) | Cloud Function instance details. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/scheduled-asset-inventory-export-bq" + billing_account = "1234-ABCD-1234" + cai_config = { + bq_dataset = "my-dataset" + bq_table = "my_table" + bq_table_overwrite = "true" + target_node = "organization/1234567890" + } + cai_gcs_export = true + file_config = { + bucket = "my-bucket" + filename = "my-folder/myfile.json" + format = "NEWLINE_DELIMITED_JSON" + bq_dataset = "my-dataset" + bq_table = "my_table" + } + project_create = true + project_id = "project-1" +} +# tftest modules=8 resources=34 +``` diff --git a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf index 1be2d1a983..85326edafe 100644 --- a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf +++ b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -94,7 +94,7 @@ module "cf" { location = var.region } bundle_config = { - source_dir = "cf" + source_dir = "${path.module}/cf" output_path = var.bundle_path } service_account = module.service-account.email @@ -118,7 +118,7 @@ module "cffile" { lifecycle_delete_age_days = null } bundle_config = { - source_dir = "cffile" + source_dir = "${path.module}/cffile" output_path = var.bundle_path_cffile excludes = null } diff --git a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/versions.tf b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/versions.tf +++ b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/README.md b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/README.md similarity index 50% rename from blueprints/cloud-operations/terraform-enterprise-wif/README.md rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/README.md index 4bb282c560..46f90ea81c 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/README.md +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/README.md @@ -1,10 +1,10 @@ -# Configuring workload identity federation for Terraform Cloud/Enterprise workflow +# Configuration of workload identity federation for Terraform Cloud/Enterprise workflows -The most common way to use Terraform Cloud for GCP deployments is to store a GCP Service Account Key as a part of TFE Workflow configuration, as we all know there are security risks due to the fact that keys are long term credentials that could be compromised. +The most common way to use Terraform Cloud for GCP deployments is to store a GCP Service Account Key as a part of TFC Workflow configuration, as we all know there are security risks due to the fact that keys are long term credentials that could be compromised. Workload identity federation enables applications running outside of Google Cloud to replace long-lived service account keys with short-lived access tokens. This is achieved by configuring Google Cloud to trust an external identity provider, so applications can use the credentials issued by the external identity provider to impersonate a service account. -This blueprint shows how to set up [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) between [Terraform Cloud/Enterprise](https://developer.hashicorp.com/terraform/enterprise) instance and Google Cloud. This will be possible by configuring workload identity federation to trust oidc tokens generated for a specific workflow in a Terraform Enterprise organization. +This blueprint shows how to set up [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) between [Terraform Cloud/Enterprise](https://developer.hashicorp.com/terraform/enterprise) instance and Google Cloud. This will be possible by configuring workload identity federation and [Terraform Cloud Dynamic Provider Credentials](https://www.hashicorp.com/blog/terraform-cloud-adds-dynamic-provider-credentials-vault-official-cloud-providers). The following diagram illustrates how the VM will get a short-lived access token and use it to access a resource: @@ -12,8 +12,8 @@ The following diagram illustrates how the VM will get a short-lived access token ## Running the blueprint -### Create Terraform Enterprise Workflow -If you don't have an existing Terraform Enterprise organization you can sign up for a [free trial](https://app.terraform.io/public/signup/account) account. +### Create Terraform Cloud Workflow +If you don't have an existing Terraform Cloud organization you can sign up for a [free trial](https://app.terraform.io/public/signup/account) account. Create a new Workspace for a `CLI-driven workflow` (Identity Federation will work for any workflow type, but for simplicity of the blueprint we use CLI driven workflow). @@ -21,7 +21,7 @@ Note workspace name and id (id starts with `ws-`), we will use them on a later s Go to the organization settings and note the org name and id (id starts with `org-`). -### Deploy GCP Workload Identity Pool Provider for Terraform Enterprise +### Deploy GCP Workload Identity Pool Provider for Terraform Cloud integration > **_NOTE:_** This is a preparation part and should be executed on behalf of a user with enough permissions. @@ -32,7 +32,7 @@ Required permissions when new project is created: - Workload Identity Admin on the project level - Project IAM Admin on the project level -Fill out required variables, use TFE Org and Workspace IDs from the previous steps (IDs are not the names). +Fill out required variables, use TFC Org and Workspace IDs from the previous steps (IDs are not the names). ```bash cd gcp-workload-identity-provider @@ -50,34 +50,41 @@ terraform init terraform apply ``` -As a result a set of outputs will be provided (your values will be different), note the output since we will use it on the next steps. +You will receive a set of outputs (your values may be different), note them because we will need them in the next steps. ``` -impersonate_service_account_email = "sa-tfe@fe-test-oidc.iam.gserviceaccount.com" -project_id = "tfe-test-oidc" -workload_identity_audience = "//iam.googleapis.com/projects/476538149566/locations/global/workloadIdentityPools/tfe-pool/providers/tfe-provider" -workload_identity_pool_provider_id = "projects/476538149566/locations/global/workloadIdentityPools/tfe-pool/providers/tfe-provider" +project_id = "tfc-dynamic-creds-gcp" +tfc_workspace_wariables = { + "TFC_GCP_PROJECT_NUMBER" = "200635100209" + "TFC_GCP_PROVIDER_AUTH" = "true" + "TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL" = "sa-tfc@tfc-dynamic-creds-gcp.iam.gserviceaccount.com" + "TFC_GCP_WORKLOAD_POOL_ID" = "tfc-pool" + "TFC_GCP_WORKLOAD_PROVIDER_ID" = "tfc-provider" +} ``` -### Configure OIDC provider for your TFE Workflow +### Configure Dynamic Provider Credentials for your TFC Workflow -To enable OIDC for a TFE workflow it's enough to setup an environment variable `TFC_WORKLOAD_IDENTITY_AUDIENCE`. +To configure [GCP Dynamic Provider Credentials](https://developer.hashicorp.com/terraform/cloud-docs/workspaces/dynamic-provider-credentials/gcp-configuration) for a TFC workflow, you need to set a set of environment variables: +- `TFC_GCP_PROVIDER_AUTH` +- `TFC_GCP_PROJECT_NUMBER` +- `TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL` +- `TFC_GCP_WORKLOAD_POOL_ID` +- `TFC_GCP_WORKLOAD_PROVIDER_ID` -Go the the Workflow -> Variables and add a new variable `TFC_WORKLOAD_IDENTITY_AUDIENCE` equal to the value of `workload_identity_audience` output, in our example it's: +Go to the Workflow -> Variables page and click the + Add variable button. For variable type select ` Environment variable`. The variable names listed above are the names of the variables that you need to set. The values provided in the terraform output in the previous step are the values that you need to provide for each variable. -``` -TFC_WORKLOAD_IDENTITY_AUDIENCE = "//iam.googleapis.com/projects/476538149566/locations/global/workloadIdentityPools/tfe-pool/providers/tfe-provider" -``` - -At that point we setup GCP Identity Federation to trust TFE generated OIDC tokens, so the TFE workflow can use the token to impersonate a GCP Service Account. +At that point we set up GCP Identity Federation to trust TFC generated OIDC tokens, workflow should be able to use Dynamic Provider Credentials to impersonate a GCP Service Account. ## Testing the blueprint -In order to test the setup we will deploy a GCS bucket from TFE Workflow using OIDC token for Service Account Impersonation. +To test the setup, we will deploy a GCS bucket from the TFC Workflow created in the previous step. + +This will allow us to verify that the workflow can successfully interact with GCP services using the TFC Dynamic Provider Credentials. ### Configure backend and variables -First, we need to configure TFE Remote backend for our testing terraform code, use TFE Organization name and workspace name (names are not the same as ids) +First, we need to configure the TFC Remote backend for our testing Terraform code. Use the TFC Organization name and workspace name (names are not the same as ids). ``` cd ../tfc-workflow-using-wif @@ -89,7 +96,7 @@ vi backend.tf ``` -Fill out variables based on the output from the preparation steps: +Fill out `project_id` variable based on the output from the preparation steps: ``` mv terraform.auto.tfvars.template terraform.auto.tfvars @@ -100,7 +107,7 @@ vi terraform.auto.tfvars ### Authenticate terraform for triggering CLI-driven workflow -Follow this [documentation](https://learn.hashicorp.com/tutorials/terraform/cloud-login) to login ti terraform cloud from the CLI. +Follow this [documentation](https://learn.hashicorp.com/tutorials/terraform/cloud-login) to login to terraform cloud from the CLI. ### Trigger the workflow @@ -110,6 +117,7 @@ terraform init terraform apply ``` -As a result we have a successfully deployed GCS bucket from Terraform Enterprise workflow using Workload Identity Federation. +As a result we have a successfully deployed GCS bucket from Terraform Cloud workflow using Workload Identity Federation. Once done testing, you can clean up resources by running `terraform destroy` first in the `tfc-workflow-using-wif` and then `gcp-workload-identity-provider` folders. + diff --git a/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/diagram.png b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/diagram.png new file mode 100644 index 0000000000..9216226ad1 Binary files /dev/null and b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/diagram.png differ diff --git a/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/README.md b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/README.md new file mode 100644 index 0000000000..1cb692d253 --- /dev/null +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/README.md @@ -0,0 +1,54 @@ +# GCP Workload Identity Provider for Terraform Cloud Dynamic Credentials + +This terraform code is a part of [GCP Workload Identity Federation for Terraform Cloud](../) blueprint. + +The codebase provisions the following list of resources: + +- (optional) GCP Project +- IAM Service Account +- Workload Identity Pool +- Workload Identity Provider +- IAM Permissins + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [billing_account](variables.tf#L16) | Billing account id used as default for new projects. | string | ✓ | | +| [project_id](variables.tf#L43) | Existing project id. | string | ✓ | | +| [tfc_organization_id](variables.tf#L48) | TFC organization id. | string | ✓ | | +| [tfc_workspace_id](variables.tf#L53) | TFC workspace id. | string | ✓ | | +| [issuer_uri](variables.tf#L21) | Terraform Cloud/Enterprise uri. Replace the uri if a self hosted instance is used. | string | | "https://app.terraform.io/" | +| [parent](variables.tf#L27) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | | null | +| [project_create](variables.tf#L37) | Create project instead of using an existing one. | bool | | true | +| [workload_identity_pool_id](variables.tf#L58) | Workload identity pool id. | string | | "tfc-pool" | +| [workload_identity_pool_provider_id](variables.tf#L64) | Workload identity pool provider id. | string | | "tfc-provider" | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [project_id](outputs.tf#L15) | GCP Project ID. | | +| [tfc_workspace_wariables](outputs.tf#L20) | Variables to be set on the TFC workspace. | | + + + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider" + billing_account = "1234-ABCD-1234" + project_create = true + project_id = "project-1" + parent = "folders/12345" + tfc_organization_id = "org-123" + tfc_workspace_id = "ws-123" + workload_identity_pool_id = "tfe-pool" + workload_identity_pool_provider_id = "tf-provider" + issuer_uri = "https://app.terraform.io/" +} + +# tftest modules=3 resources=12 +``` diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/main.tf b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/main.tf similarity index 77% rename from blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/main.tf rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/main.tf index 5ced2e3c57..e4275350d5 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/main.tf +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/main.tf @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -36,25 +36,27 @@ module "project" { # Workload Identity Pool and Provider # ############################################################################### -resource "google_iam_workload_identity_pool" "tfe-pool" { +resource "google_iam_workload_identity_pool" "tfc-pool" { project = module.project.project_id workload_identity_pool_id = var.workload_identity_pool_id - display_name = "TFE Pool" - description = "Identity pool for Terraform Enterprise OIDC integration" + display_name = "TFC Pool" + description = "Identity pool for Terraform Cloud Dynamic Credentials integration" } -resource "google_iam_workload_identity_pool_provider" "tfe-pool-provider" { +resource "google_iam_workload_identity_pool_provider" "tfc-pool-provider" { project = module.project.project_id - workload_identity_pool_id = google_iam_workload_identity_pool.tfe-pool.workload_identity_pool_id + workload_identity_pool_id = google_iam_workload_identity_pool.tfc-pool.workload_identity_pool_id workload_identity_pool_provider_id = var.workload_identity_pool_provider_id - display_name = "TFE Pool Provider" - description = "OIDC identity pool provider for TFE Integration" - # Use condition to make sure only token generated for a specific TFE Org can be used across org workspaces - attribute_condition = "attribute.terraform_organization_id == \"${var.tfe_organization_id}\"" + display_name = "TFC Pool Provider" + description = "OIDC identity pool provider for Terraform Cloud Dynamic Credentials integration" + # Use condition to make sure only token generated for a specific TFC Org can be used across org workspaces + attribute_condition = "attribute.terraform_organization_id == \"${var.tfc_organization_id}\"" attribute_mapping = { "google.subject" = "assertion.sub" "attribute.aud" = "assertion.aud" "attribute.terraform_run_phase" = "assertion.terraform_run_phase" + "attribute.terraform_project_id" = "assertion.terraform_project_id", + "attribute.terraform_project_name" = "assertion.terraform_project_name", "attribute.terraform_workspace_id" = "assertion.terraform_workspace_id" "attribute.terraform_workspace_name" = "assertion.terraform_workspace_name" "attribute.terraform_organization_id" = "assertion.terraform_organization_id" @@ -72,15 +74,15 @@ resource "google_iam_workload_identity_pool_provider" "tfe-pool-provider" { # Service Account and IAM bindings # ############################################################################### -module "sa-tfe" { +module "sa-tfc" { source = "../../../../modules/iam-service-account" project_id = module.project.project_id - name = "sa-tfe" + name = "sa-tfc" iam = { - # We allow only tokens generated by a specific TFE workspace impersonation of the service account, - # that way one identity pool can be used for a TFE Organization, but every workspace will be able to impersonate only a specifc SA - "roles/iam.workloadIdentityUser" = ["principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.tfe-pool.name}/attribute.terraform_workspace_id/${var.tfe_workspace_id}"] + # We allow only tokens generated by a specific TFC workspace impersonation of the service account, + # that way one identity pool can be used for a TFC Organization, but every workspace will be able to impersonate only a specifc SA + "roles/iam.workloadIdentityUser" = ["principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.tfc-pool.name}/attribute.terraform_workspace_id/${var.tfc_workspace_id}"] } iam_project_roles = { diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/outputs.tf b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/outputs.tf similarity index 53% rename from blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/outputs.tf rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/outputs.tf index 46d7f6b0f2..e38a4da668 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/outputs.tf +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/outputs.tf @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -12,23 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. - -output "impersonate_service_account_email" { - description = "Service account to be impersonated by workload identity." - value = module.sa-tfe.email -} - output "project_id" { description = "GCP Project ID." value = module.project.project_id } -output "workload_identity_audience" { - description = "TFC Workload Identity Audience." - value = "//iam.googleapis.com/${google_iam_workload_identity_pool_provider.tfe-pool-provider.name}" -} - -output "workload_identity_pool_provider_id" { - description = "GCP workload identity pool provider ID." - value = google_iam_workload_identity_pool_provider.tfe-pool-provider.name +output "tfc_workspace_wariables" { + description = "Variables to be set on the TFC workspace." + value = { + TFC_GCP_PROVIDER_AUTH = "true", + TFC_GCP_PROJECT_NUMBER = module.project.number, + TFC_GCP_WORKLOAD_POOL_ID = google_iam_workload_identity_pool.tfc-pool.workload_identity_pool_id, + TFC_GCP_WORKLOAD_PROVIDER_ID = google_iam_workload_identity_pool_provider.tfc-pool-provider.workload_identity_pool_provider_id, + TFC_GCP_RUN_SERVICE_ACCOUNT_EMAIL = module.sa-tfc.email + } } diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/variables.tf b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/variables.tf similarity index 83% rename from blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/variables.tf rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/variables.tf index 3719b1839e..3d4da65892 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/variables.tf +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/gcp-workload-identity-provider/variables.tf @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -19,7 +19,7 @@ variable "billing_account" { } variable "issuer_uri" { - description = "Terraform Enterprise uri. Replace the uri if a self hosted instance is used." + description = "Terraform Cloud/Enterprise uri. Replace the uri if a self hosted instance is used." type = string default = "https://app.terraform.io/" } @@ -45,24 +45,24 @@ variable "project_id" { type = string } -variable "tfe_organization_id" { - description = "TFE organization id." +variable "tfc_organization_id" { + description = "TFC organization id." type = string } -variable "tfe_workspace_id" { - description = "TFE workspace id." +variable "tfc_workspace_id" { + description = "TFC workspace id." type = string } variable "workload_identity_pool_id" { description = "Workload identity pool id." type = string - default = "tfe-pool" + default = "tfc-pool" } variable "workload_identity_pool_provider_id" { description = "Workload identity pool provider id." type = string - default = "tfe-provider" + default = "tfc-provider" } diff --git a/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/README.md b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/README.md new file mode 100644 index 0000000000..262472d03a --- /dev/null +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/README.md @@ -0,0 +1,16 @@ +# Test GCP Workload Identity Provider for Terraform Dynamic Credentials + +This terraform code is a part of [GCP Workload Identity Federation for Terraform Cloud](../) blueprint. For instructions please refer to the blueprint [readme](../README.md). + +The codebase provisions the following list of resources: + +- GCS Bucket + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [project_id](variables.tf#L15) | GCP project ID. | string | ✓ | | + + diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/backend.tf.template b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/backend.tf.template similarity index 89% rename from blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/backend.tf.template rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/backend.tf.template index 87d4737dfb..01781fe97e 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/backend.tf.template +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/backend.tf.template @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -18,10 +18,10 @@ terraform { backend "remote" { - organization = "" + organization = "" workspaces { - name = "" + name = "" } } diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/main.tf b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/main.tf similarity index 91% rename from blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/main.tf rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/main.tf index 5e03ada5fb..692447d1bb 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/main.tf +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/main.tf @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -19,7 +19,7 @@ resource "google_storage_bucket" "test-bucket" { project = var.project_id - name = "${var.project_id}-tfe-oidc-test-bucket" + name = "${var.project_id}-test" location = "US" force_destroy = true } diff --git a/tests/blueprints/networking/filtering_proxy/fixture/variables.tf b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/provider.tf similarity index 86% rename from tests/blueprints/networking/filtering_proxy/fixture/variables.tf rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/provider.tf index f4b4c588c3..cc83fd710b 100644 --- a/tests/blueprints/networking/filtering_proxy/fixture/variables.tf +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/provider.tf @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -12,7 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -variable "mig" { - type = bool - default = false -} +provider "google" {} diff --git a/tests/blueprints/data_solutions/shielded_folder/tftest.yaml b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/terraform.auto.tfvars.template similarity index 81% rename from tests/blueprints/data_solutions/shielded_folder/tftest.yaml rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/terraform.auto.tfvars.template index 3c0bcb8c42..55bfe82e12 100644 --- a/tests/blueprints/data_solutions/shielded_folder/tftest.yaml +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/terraform.auto.tfvars.template @@ -4,7 +4,7 @@ # 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 +# https://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, @@ -12,7 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -module: blueprints/data-solutions/shielded-folder - -tests: - simple: +project_id = "tfc-dynamic-creds-gcp" diff --git a/tests/blueprints/cloud_operations/iam_delegated_role_grants/fixture/variables.tf b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/variables.tf similarity index 91% rename from tests/blueprints/cloud_operations/iam_delegated_role_grants/fixture/variables.tf rename to blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/variables.tf index 626af01198..3fc54afb90 100644 --- a/tests/blueprints/cloud_operations/iam_delegated_role_grants/fixture/variables.tf +++ b/blueprints/cloud-operations/terraform-cloud-dynamic-credentials/tfc-workflow-using-wif/variables.tf @@ -13,6 +13,6 @@ # limitations under the License. variable "project_id" { - type = string - default = "project-1" + description = "GCP project ID." + type = string } diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/diagram.png b/blueprints/cloud-operations/terraform-enterprise-wif/diagram.png deleted file mode 100644 index d4e6f82e9d..0000000000 Binary files a/blueprints/cloud-operations/terraform-enterprise-wif/diagram.png and /dev/null differ diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/README.md b/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/README.md deleted file mode 100644 index 35198e8d1c..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# GCP Workload Identity Provider for Terraform Enterprise - -This terraform code is a part of [GCP Workload Identity Federation for Terraform Enterprise](../) blueprint. - -The codebase provisions the following list of resources: - -- GCS Bucket - - -## Variables - -| name | description | type | required | default | -|---|---|:---:|:---:|:---:| -| [billing_account](variables.tf#L16) | Billing account id used as default for new projects. | string | ✓ | | -| [project_id](variables.tf#L43) | Existing project id. | string | ✓ | | -| [tfe_organization_id](variables.tf#L48) | TFE organization id. | string | ✓ | | -| [tfe_workspace_id](variables.tf#L53) | TFE workspace id. | string | ✓ | | -| [issuer_uri](variables.tf#L21) | Terraform Enterprise uri. Replace the uri if a self hosted instance is used. | string | | "https://app.terraform.io/" | -| [parent](variables.tf#L27) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | | null | -| [project_create](variables.tf#L37) | Create project instead of using an existing one. | bool | | true | -| [workload_identity_pool_id](variables.tf#L58) | Workload identity pool id. | string | | "tfe-pool" | -| [workload_identity_pool_provider_id](variables.tf#L64) | Workload identity pool provider id. | string | | "tfe-provider" | - -## Outputs - -| name | description | sensitive | -|---|---|:---:| -| [impersonate_service_account_email](outputs.tf#L16) | Service account to be impersonated by workload identity. | | -| [project_id](outputs.tf#L21) | GCP Project ID. | | -| [workload_identity_audience](outputs.tf#L26) | TFC Workload Identity Audience. | | -| [workload_identity_pool_provider_id](outputs.tf#L31) | GCP workload identity pool provider ID. | | - - diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/terraform.auto.tfvars.template b/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/terraform.auto.tfvars.template deleted file mode 100644 index 645eea0b9c..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider/terraform.auto.tfvars.template +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - - -parent = "folders/437102807785" -project_id = "my-project-id" -tfe_organization_id = "org-W3bz9neazHrZz99U" -tfe_workspace_id = "ws-DFxEE3NmeMdaAvoK" -billing_account = "015617-1B8CBC-AF10D9" diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/README.md b/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/README.md deleted file mode 100644 index 9b292de62a..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# GCP Workload Identity Provider for Terraform Enterprise - -This terraform code is a part of [GCP Workload Identity Federation for Terraform Enterprise](../) blueprint. For instructions please refer to the blueprint [readme](../README.md). - -The codebase provisions the following list of resources: - -- GCS Bucket - - -## Variables - -| name | description | type | required | default | -|---|---|:---:|:---:|:---:| -| [impersonate_service_account_email](variables.tf#L16) | Service account to be impersonated by workload identity. | string | ✓ | | -| [project_id](variables.tf#L21) | GCP project ID. | string | ✓ | | - - diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/provider.tf b/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/provider.tf deleted file mode 100644 index ae132fd40b..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/provider.tf +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - - -module "tfe_oidc" { - source = "./tfc-oidc" - - impersonate_service_account_email = var.impersonate_service_account_email -} - -provider "google" { - credentials = module.tfe_oidc.credentials -} diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/terraform.auto.tfvars.template b/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/terraform.auto.tfvars.template deleted file mode 100644 index fc2811db53..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/terraform.auto.tfvars.template +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -project_id = "tfe-oidc-workflow" -impersonate_service_account_email = "sa-tfe@tfe-oidc-workflow2.iam.gserviceaccount.com" diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/README.md b/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/README.md deleted file mode 100644 index fd869ae1ae..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Terraform Enterprise OIDC Credential for GCP Workload Identity Federation - -This is a helper module to prepare GCP Credentials from Terraform Enterprise workload identity token. For more information see [Terraform Enterprise Workload Identity Federation](../) blueprint. - -## Example -```hcl -module "tfe_oidc" { - source = "./tfc-oidc" - - impersonate_service_account_email = "tfe-test@tfe-test-wif.iam.gserviceaccount.com" -} - -provider "google" { - credentials = module.tfe_oidc.credentials -} - -provider "google-beta" { - credentials = module.tfe_oidc.credentials -} - -# tftest skip -``` - - -## Variables - -| name | description | type | required | default | -|---|---|:---:|:---:|:---:| -| [impersonate_service_account_email](variables.tf#L17) | Service account to be impersonated by workload identity federation. | string | ✓ | | -| [tmp_oidc_token_path](variables.tf#L22) | Name of the temporary file where TFC OIDC token will be stored to authentificate terraform provider google. | string | | ".oidc_token" | - -## Outputs - -| name | description | sensitive | -|---|---|:---:| -| [credentials](outputs.tf#L17) | Credentials in format to pass the to gcp provider. | | - - diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/get_audience.sh b/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/get_audience.sh deleted file mode 100644 index 251fe321d0..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/get_audience.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Copyright 2022 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 -# -# https://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. - -# Exit if any of the intermediate steps fail -set -e - -cat < $FILENAME - -echo -n "{\"file\":\"${FILENAME}\"}" diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/variables.tf b/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/variables.tf deleted file mode 100644 index bc9ca9f8cd..0000000000 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/variables.tf +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - - -variable "impersonate_service_account_email" { - description = "Service account to be impersonated by workload identity." - type = string -} - -variable "project_id" { - description = "GCP project ID." - type = string -} diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/README.md b/blueprints/cloud-operations/unmanaged-instances-healthcheck/README.md index a3a21dbd27..29721ac12f 100644 --- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/README.md +++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/README.md @@ -118,3 +118,15 @@ gcloud compute ssh --zone europe-west1-b nginx-test -- 'uptime' | [pubsub-topic](outputs.tf#L26) | Restarter PubSub topic. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/unmanaged-instances-healthcheck" + project_id = "project-1" + billing_account = "123456-123456-123456" + project_create = true +} +# tftest modules=11 resources=35 +``` diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.mod b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.mod index 8c500ff27c..f673f29d2f 100644 --- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.mod +++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.mod @@ -3,14 +3,12 @@ module example.com/healthckecker go 1.16 require ( - cloud.google.com/go/iam v0.3.0 // indirect - cloud.google.com/go/pubsub v1.19.0 + cloud.google.com/go v0.110.0 // indirect + cloud.google.com/go/iam v0.12.0 // indirect + cloud.google.com/go/pubsub v1.28.0 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/jstemmer/go-junit-report v1.0.0 // indirect - golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect - golang.org/x/tools v0.1.9 // indirect - google.golang.org/api v0.71.0 - google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 // indirect - google.golang.org/grpc v1.45.0 // indirect + golang.org/x/net v0.7.0 + golang.org/x/text v0.7.0 + google.golang.org/api v0.110.0 + google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 // indirect ) diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.sum b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.sum index 7024e7d8f5..1a972c4989 100644 --- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.sum +++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/healthchecker/go.sum @@ -3,6 +3,7 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -15,58 +16,401 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0 h1:MjvSkUq8RuAb+2JLDi5VQmmExRJPUQ3JLCWpRB6fmdw= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= +cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= +cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= +cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= +cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= +cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= +cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= +cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= +cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= +cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno= +cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= +cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ= +cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= +cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= +cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= +cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= +cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= +cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE= +cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE= +cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4= +cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= +cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= +cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= +cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= +cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= +cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= +cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= +cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= +cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= +cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= +cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= +cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= +cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= +cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= +cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= +cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= +cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE= +cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= +cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= +cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= +cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= +cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= +cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= +cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= +cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= +cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek= +cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0= +cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= +cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= +cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= +cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= +cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= +cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= +cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= +cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= +cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= +cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= +cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= +cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= +cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= +cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= +cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= +cloud.google.com/go/iam v0.12.0 h1:DRtTY29b75ciH6Ov1PHb4/iat2CLCvrOm40Q0a6DFpE= +cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= +cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= +cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A= +cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= +cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= +cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= +cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0 h1:OWRZzrPmOZUzurjI2FBGtgY2mB1WaJkqhw6oIwSj0Yg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= +cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= +cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= +cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= +cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= +cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= +cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= +cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= +cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= +cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= +cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= +cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= +cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= +cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= +cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= +cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= +cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= +cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= +cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= +cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= +cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= +cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= +cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.15.0 h1:6KI/wDVYLtNvzIPJ8ObuJcq5bBtAWQ6Suo8osHPvYn4= -cloud.google.com/go/pubsub v1.15.0/go.mod h1:DnEUPGZlp+N9MElp/6uVqCKiknQixvVLcrgrqT62O6A= -cloud.google.com/go/pubsub v1.19.0 h1:WZy66ga6/tqmZiwv1jwKVgqV8FuEuAmPR5CEJHNVCZk= -cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= +cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= +cloud.google.com/go/pubsub v1.28.0 h1:XzabfdPx/+eNrsVVGLFgeUnQQKPGkMb8klRCeYK52is= +cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= +cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE= +cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= +cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= +cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= +cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= +cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= +cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= +cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= +cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= +cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= +cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk= +cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= +cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q= +cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= +cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= +cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= +cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4= +cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= +cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= +cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= +cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E= +cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU= +cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= +cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= +cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= +cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w= +cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= +cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= +cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= +cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= +cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= +cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= +cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= +cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= +cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= +cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= +cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= +cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= +cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY= +cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= +cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= +cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= +cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= +cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= +cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= +cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= +cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= +cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= +cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -75,11 +419,16 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -88,15 +437,19 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -141,14 +494,16 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -158,6 +513,7 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -165,56 +521,93 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jstemmer/go-junit-report v1.0.0 h1:8X1gzZpR+nVQLAht+L/foqOeX2l9DTZoaIPbEQHxsds= -github.com/jstemmer/go-junit-report v1.0.0/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -238,7 +631,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -250,10 +642,10 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -284,16 +676,30 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -307,13 +713,21 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a h1:4Kd8OPUx1xgUwrHDaviWZO8MsgoZTZYC3g+8m16RBww= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= +golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -324,8 +738,12 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -358,33 +776,48 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -392,15 +825,19 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -446,20 +883,23 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -485,18 +925,35 @@ google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59t google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0 h1:ECJUVngj71QI6XEm7b1sAf8BljU5inEhMbKPR8Lxhhk= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0 h1:SgWof18M8V2NylsX7bL4fM28j+nFdRopHZbdipaaw20= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= +google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -540,10 +997,13 @@ google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -554,16 +1014,13 @@ google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c h1:iLQakcwWG3k/++1q/46apVb1sUQ3IqIdn9yUE6eh/xA= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= @@ -573,8 +1030,56 @@ google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 h1:FglFEfyj61zP3c6LgjmVHxYxZWXYul9oiS1EZqD5gLc= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= +google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE= +google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923 h1:znp6mq/drrY+6khTAlJUDNFFcDGV2ENLYKpMq8SyCds= +google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -598,13 +1103,22 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1 h1:f37vZbBVTiJ6jKG5mWz8ySOBxNqy6ViPgyhSdVnxF3E= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -618,14 +1132,17 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.mod b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.mod index 6754eb1093..a6b7b2778e 100644 --- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.mod +++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.mod @@ -4,14 +4,10 @@ go 1.16 require ( cloud.google.com/go/iam v0.3.0 // indirect - cloud.google.com/go/logging v1.4.2 cloud.google.com/go/pubsub v1.19.0 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect - github.com/jstemmer/go-junit-report v1.0.0 // indirect golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect - golang.org/x/tools v0.1.9 // indirect + golang.org/x/sys v0.1.0 // indirect google.golang.org/api v0.71.0 google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 // indirect google.golang.org/grpc v1.45.0 // indirect diff --git a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.sum b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.sum index 1f4ca61d68..f63000547d 100644 --- a/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.sum +++ b/blueprints/cloud-operations/unmanaged-instances-healthcheck/function/restarter/go.sum @@ -21,10 +21,7 @@ cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.88.0/go.mod h1:dnKwfYbP9hQhefiUvpbcAyoGSHUrOxR20JVElLiUvEY= cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.91.1 h1:w+u8ttN/QtYrpvgXNUd2G6kwqrqCIQbkINlXQjHP1ek= -cloud.google.com/go v0.91.1/go.mod h1:V358WZfbFQkmC3gv5XCxzZq2e3h7OGvQR0IXtj77ylI= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= @@ -47,13 +44,11 @@ cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1 cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/kms v1.1.0 h1:1yc4rLqCkVDS9Zvc7m+3mJ47kw0Uo5Q5+sMjcmUVUeM= cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= -cloud.google.com/go/logging v1.4.2 h1:Mu2Q75VBDQlW1HlBMjTX4X84UFR73G1TiLlRYc/b7tA= -cloud.google.com/go/logging v1.4.2/go.mod h1:jco9QZSx8HiVVqLJReq7z7bVdj0P1Jb9PDFs63T+axo= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.19.0 h1:WZy66ga6/tqmZiwv1jwKVgqV8FuEuAmPR5CEJHNVCZk= cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= @@ -99,7 +94,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -144,7 +138,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= @@ -165,13 +158,10 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= @@ -182,10 +172,7 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jstemmer/go-junit-report v1.0.0 h1:8X1gzZpR+nVQLAht+L/foqOeX2l9DTZoaIPbEQHxsds= -github.com/jstemmer/go-junit-report v1.0.0/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -205,7 +192,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -243,7 +229,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -255,10 +240,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -293,9 +275,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -310,10 +290,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a h1:4Kd8OPUx1xgUwrHDaviWZO8MsgoZTZYC3g+8m16RBww= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -369,27 +347,24 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -399,7 +374,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -457,10 +431,7 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -487,13 +458,10 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.52.0 h1:m5FLEd6dp5CU1F0tMWyqDi2XjchviIz8ntzOSz7w8As= -google.golang.org/api v0.52.0/go.mod h1:Him/adpjt0sxtkWViy0b6xyKW/SD71CwdJ7HqJo7SrU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= @@ -553,21 +521,15 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210811021853-ddbe55d93216/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c h1:iLQakcwWG3k/++1q/46apVb1sUQ3IqIdn9yUE6eh/xA= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= @@ -611,7 +573,6 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1 h1:f37vZbBVTiJ6jKG5mWz8ySOBxNqy6ViPgyhSdVnxF3E= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= diff --git a/blueprints/cloud-operations/vm-migration/host-target-projects/README.md b/blueprints/cloud-operations/vm-migration/host-target-projects/README.md index c1d241824f..ae602bda19 100644 --- a/blueprints/cloud-operations/vm-migration/host-target-projects/README.md +++ b/blueprints/cloud-operations/vm-migration/host-target-projects/README.md @@ -38,3 +38,30 @@ This sample creates\updates several distinct groups of resources: | [m4ce_gmanaged_service_account](outputs.tf#L15) | Google managed service account created automatically during the migrate connector registration.. It is used by M4CE to perform activities on target projects. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/vm-migration/host-target-projects" + project_create = { + billing_account_id = "1234-ABCD-1234" + parent = "folders/1234563" + } + migration_admin_users = ["user:admin@example.com"] + migration_viewer_users = ["user:viewer@example.com"] + migration_target_projects = [module.test-target-project.name] + depends_on = [ + module.test-target-project + ] +} + +module "test-target-project" { + source = "./fabric/modules/project" + billing_account = "1234-ABCD-1234" + name = "test-target-project" + project_create = true +} + +# tftest modules=5 resources=24 +``` diff --git a/blueprints/cloud-operations/vm-migration/host-target-sharedvpc/README.md b/blueprints/cloud-operations/vm-migration/host-target-sharedvpc/README.md index bb34cf8ff3..fe5c9e82c2 100644 --- a/blueprints/cloud-operations/vm-migration/host-target-sharedvpc/README.md +++ b/blueprints/cloud-operations/vm-migration/host-target-sharedvpc/README.md @@ -42,3 +42,39 @@ This sample creates\update several distinct groups of resources: ## Manual Steps Once this blueprint is deployed the M4CE [m4ce_gmanaged_service_account](https://cloud.google.com/migrate/compute-engine/docs/5.0/how-to/target-sa-compute-engine#configuring_the_default_service_account) has to be configured to grant the access to the shared VPC and allow the deploy of Compute Engine instances as the result of the migration. + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/vm-migration/host-target-sharedvpc" + project_create = { + billing_account_id = "1234-ABCD-1234" + parent = "folders/1234563" + } + migration_admin_users = ["user:admin@example.com"] + migration_viewer_users = ["user:viewer@example.com"] + migration_target_projects = [module.test-target-project.name] + sharedvpc_host_projects = [module.test-sharedvpc-host-project.name] + depends_on = [ + module.test-target-project, + module.test-sharedvpc-host-project, + ] +} + +module "test-target-project" { + source = "./fabric/modules/project" + billing_account = "1234-ABCD-1234" + name = "test-target-project" + project_create = true +} + +module "test-sharedvpc-host-project" { + source = "./fabric/modules/project" + billing_account = "1234-ABCD-1234" + name = "test-sharedvpc-host-project" + project_create = true +} + +# tftest modules=7 resources=25 +``` diff --git a/blueprints/cloud-operations/vm-migration/single-project/README.md b/blueprints/cloud-operations/vm-migration/single-project/README.md index 20afd4a9b4..697d81977f 100644 --- a/blueprints/cloud-operations/vm-migration/single-project/README.md +++ b/blueprints/cloud-operations/vm-migration/single-project/README.md @@ -39,3 +39,18 @@ This sample creates several distinct groups of resources: | [m4ce_gmanaged_service_account](outputs.tf#L15) | Google managed service account created automatically during the migrate connector registration. It is used by M4CE to perform activities on target projects. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/cloud-operations/vm-migration/single-project" + project_create = { + billing_account_id = "1234-ABCD-1234" + parent = "folders/1234563" + } + migration_admin_users = ["user:admin@example.com"] + migration_viewer_users = ["user:viewer@example.com"] +} +# tftest modules=5 resources=20 +``` diff --git a/blueprints/data-solutions/cloudsql-multiregion/README.md b/blueprints/data-solutions/cloudsql-multiregion/README.md index d6420d6c91..8b8e7e3e35 100644 --- a/blueprints/data-solutions/cloudsql-multiregion/README.md +++ b/blueprints/data-solutions/cloudsql-multiregion/README.md @@ -165,3 +165,20 @@ The above command will delete the associated resources so there will be no billa | [service_accounts](outputs.tf#L46) | Service Accounts. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/cloudsql-multiregion/" + data_eng_principals = ["dataeng@example.com"] + postgres_user_password = "my-root-password" + project_id = "project" + project_create = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + prefix = "prefix" +} +# tftest modules=10 resources=50 +``` diff --git a/blueprints/data-solutions/cmek-via-centralized-kms/README.md b/blueprints/data-solutions/cmek-via-centralized-kms/README.md index 3813c90c2f..ab80d5ff8e 100644 --- a/blueprints/data-solutions/cmek-via-centralized-kms/README.md +++ b/blueprints/data-solutions/cmek-via-centralized-kms/README.md @@ -54,3 +54,17 @@ This sample creates several distinct groups of resources: | [vm_keys](outputs.tf#L41) | GCE VM Cloud KMS crypto keys. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/cmek-via-centralized-kms/" + project_config = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + prefix = "prefix" +} +# tftest modules=8 resources=27 +``` diff --git a/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf b/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf +++ b/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/data-solutions/composer-2/README.md b/blueprints/data-solutions/composer-2/README.md index bc51aaa4fb..6ff0e8b08a 100644 --- a/blueprints/data-solutions/composer-2/README.md +++ b/blueprints/data-solutions/composer-2/README.md @@ -113,3 +113,18 @@ service_encryption_keys = { | [composer_dag_gcs](outputs.tf#L22) | The Cloud Storage prefix of the DAGs for the Cloud Composer environment. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/composer-2/" + project_id = "project" + project_create = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + prefix = "prefix" +} +# tftest modules=5 resources=26 +``` diff --git a/blueprints/data-solutions/data-platform-foundations/01-dropoff.tf b/blueprints/data-solutions/data-platform-foundations/01-dropoff.tf index 177f940a86..46e9a1309a 100644 --- a/blueprints/data-solutions/data-platform-foundations/01-dropoff.tf +++ b/blueprints/data-solutions/data-platform-foundations/01-dropoff.tf @@ -15,36 +15,34 @@ # tfdoc:file:description drop off project and resources. locals { - drop_orch_service_accounts = [ - module.load-sa-df-0.iam_email, module.orch-sa-cmp-0.iam_email - ] -} - -module "drop-project" { - source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "drp${local.project_suffix}" - group_iam = { - (local.groups.data-engineers) = [ - "roles/bigquery.dataEditor", - "roles/pubsub.editor", - "roles/storage.admin", + iam_drp = { + "roles/bigquery.dataEditor" = [ + module.drop-sa-bq-0.iam_email, local.groups_iam.data-engineers + ] + "roles/bigquery.user" = [ + module.load-sa-df-0.iam_email, local.groups_iam.data-engineers + ] + "roles/pubsub.publisher" = [module.drop-sa-ps-0.iam_email] + "roles/pubsub.subscriber" = [ + module.orch-sa-cmp-0.iam_email, module.load-sa-df-0.iam_email ] - } - iam = { - "roles/bigquery.dataEditor" = [module.drop-sa-bq-0.iam_email] - "roles/bigquery.user" = [module.load-sa-df-0.iam_email] - "roles/pubsub.publisher" = [module.drop-sa-ps-0.iam_email] - "roles/pubsub.subscriber" = concat( - local.drop_orch_service_accounts, [module.load-sa-df-0.iam_email] - ) - "roles/storage.objectAdmin" = [module.load-sa-df-0.iam_email] "roles/storage.objectCreator" = [module.drop-sa-cs-0.iam_email] "roles/storage.objectViewer" = [module.orch-sa-cmp-0.iam_email] - "roles/storage.admin" = [module.load-sa-df-0.iam_email] + "roles/storage.objectAdmin" = [ + module.load-sa-df-0.iam_email, module.load-sa-df-0.iam_email + ] } +} + +module "drop-project" { + source = "../../../modules/project" + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.drop : "${var.project_config.project_ids.drop}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.iam_drp : null + iam_additive = var.project_config.billing_account_id == null ? local.iam_drp : null services = concat(var.project_services, [ "bigquery.googleapis.com", "bigqueryreservation.googleapis.com", diff --git a/blueprints/data-solutions/data-platform-foundations/02-load.tf b/blueprints/data-solutions/data-platform-foundations/02-load.tf index 74cb9f8b0c..9702fce1ec 100644 --- a/blueprints/data-solutions/data-platform-foundations/02-load.tf +++ b/blueprints/data-solutions/data-platform-foundations/02-load.tf @@ -15,6 +15,19 @@ # tfdoc:file:description Load project and VPC. locals { + iam_load = { + "roles/bigquery.jobUser" = [module.load-sa-df-0.iam_email] + "roles/dataflow.admin" = [ + module.orch-sa-cmp-0.iam_email, + module.load-sa-df-0.iam_email, + local.groups_iam.data-engineers + ] + "roles/dataflow.developer" = [ + local.groups_iam.data-engineers + ] + "roles/dataflow.worker" = [module.load-sa-df-0.iam_email] + "roles/storage.objectAdmin" = local.load_service_accounts + } load_service_accounts = [ "serviceAccount:${module.load-project.service_accounts.robots.dataflow}", module.load-sa-df-0.iam_email @@ -35,26 +48,13 @@ locals { module "load-project" { source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "lod${local.project_suffix}" - group_iam = { - (local.groups.data-engineers) = [ - "roles/compute.viewer", - "roles/dataflow.admin", - "roles/dataflow.developer", - "roles/viewer", - ] - } - iam = { - "roles/bigquery.jobUser" = [module.load-sa-df-0.iam_email] - "roles/dataflow.admin" = [ - module.orch-sa-cmp-0.iam_email, module.load-sa-df-0.iam_email - ] - "roles/dataflow.worker" = [module.load-sa-df-0.iam_email] - "roles/storage.objectAdmin" = local.load_service_accounts - } + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.load : "${var.project_config.project_ids.load}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.iam_load : null + iam_additive = var.project_config.billing_account_id == null ? local.iam_load : null services = concat(var.project_services, [ "bigquery.googleapis.com", "bigqueryreservation.googleapis.com", @@ -86,8 +86,13 @@ module "load-sa-df-0" { name = "load-df-0" display_name = "Data platform Dataflow load service account" iam = { - "roles/iam.serviceAccountTokenCreator" = [local.groups_iam.data-engineers] - "roles/iam.serviceAccountUser" = [module.orch-sa-cmp-0.iam_email] + "roles/iam.serviceAccountTokenCreator" = [ + local.groups_iam.data-engineers, + module.orch-sa-cmp-0.iam_email + ], + "roles/iam.serviceAccountUser" = [ + module.orch-sa-cmp-0.iam_email + ] } } @@ -107,11 +112,11 @@ module "load-vpc" { source = "../../../modules/net-vpc" count = local.use_shared_vpc ? 0 : 1 project_id = module.load-project.project_id - name = "${var.prefix}-default" + name = "${var.prefix}-lod" subnets = [ { ip_cidr_range = "10.10.0.0/24" - name = "default" + name = "${var.prefix}-lod" region = var.region } ] @@ -131,7 +136,7 @@ module "load-nat" { source = "../../../modules/net-cloudnat" count = local.use_shared_vpc ? 0 : 1 project_id = module.load-project.project_id - name = "${var.prefix}-default" + name = "${var.prefix}-lod" region = var.region router_network = module.load-vpc.0.name } diff --git a/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf b/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf index a202afdd05..fc0eda12e6 100644 --- a/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf +++ b/blueprints/data-solutions/data-platform-foundations/03-orchestration.tf @@ -15,52 +15,22 @@ # tfdoc:file:description Orchestration project and VPC. locals { - orch_subnet = ( - local.use_shared_vpc - ? var.network_config.subnet_self_links.orchestration - : values(module.orch-vpc.0.subnet_self_links)[0] - ) - orch_vpc = ( - local.use_shared_vpc - ? var.network_config.network_self_link - : module.orch-vpc.0.self_link - ) - - # Note: This formatting is needed for output purposes since the fabric artifact registry - # module doesn't yet expose the docker usage path of a registry folder in the needed format. - orch_docker_path = format("%s-docker.pkg.dev/%s/%s", - var.region, module.orch-project.project_id, module.orch-artifact-reg.name) -} - -module "orch-project" { - source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "orc${local.project_suffix}" - group_iam = { - (local.groups.data-engineers) = [ - "roles/bigquery.dataEditor", - "roles/bigquery.jobUser", - "roles/cloudbuild.builds.editor", - "roles/composer.admin", - "roles/composer.environmentAndStorageObjectAdmin", - "roles/iap.httpsResourceAccessor", - "roles/iam.serviceAccountUser", - "roles/storage.objectAdmin", - "roles/storage.admin", - "roles/artifactregistry.admin", - "roles/serviceusage.serviceUsageConsumer", - ] - } - iam = { + iam_orch = { + "roles/artifactregistry.admin" = [local.groups_iam.data-engineers] + "roles/artifactregistry.reader" = [module.load-sa-df-0.iam_email] "roles/bigquery.dataEditor" = [ module.load-sa-df-0.iam_email, module.transf-sa-df-0.iam_email, + local.groups_iam.data-engineers ] "roles/bigquery.jobUser" = [ module.orch-sa-cmp-0.iam_email, + local.groups_iam.data-engineers ] + "roles/cloudbuild.builds.editor" = [local.groups_iam.data-engineers] + "roles/cloudbuild.serviceAgent" = [module.orch-sa-df-build.iam_email] + "roles/composer.admin" = [local.groups_iam.data-engineers] + "roles/composer.environmentAndStorageObjectAdmin" = [local.groups_iam.data-engineers] "roles/composer.ServiceAgentV2Ext" = [ "serviceAccount:${module.orch-project.service_accounts.robots.composer}" ] @@ -68,23 +38,46 @@ module "orch-project" { module.orch-sa-cmp-0.iam_email ] "roles/iam.serviceAccountUser" = [ - module.orch-sa-cmp-0.iam_email + module.orch-sa-cmp-0.iam_email, local.groups_iam.data-engineers ] + "roles/iap.httpsResourceAccessor" = [local.groups_iam.data-engineers] + "roles/serviceusage.serviceUsageConsumer" = [local.groups_iam.data-engineers] "roles/storage.objectAdmin" = [ module.orch-sa-cmp-0.iam_email, module.orch-sa-df-build.iam_email, "serviceAccount:${module.orch-project.service_accounts.robots.composer}", "serviceAccount:${module.orch-project.service_accounts.robots.cloudbuild}", - ] - "roles/artifactregistry.reader" = [ - module.load-sa-df-0.iam_email, - ] - "roles/cloudbuild.serviceAgent" = [ - module.orch-sa-df-build.iam_email, + local.groups_iam.data-engineers ] "roles/storage.objectViewer" = [module.load-sa-df-0.iam_email] } - oslogin = false + orch_subnet = ( + local.use_shared_vpc + ? var.network_config.subnet_self_links.orchestration + : values(module.orch-vpc.0.subnet_self_links)[0] + ) + orch_vpc = ( + local.use_shared_vpc + ? var.network_config.network_self_link + : module.orch-vpc.0.self_link + ) + + # Note: This formatting is needed for output purposes since the fabric artifact registry + # module doesn't yet expose the docker usage path of a registry folder in the needed format. + orch_docker_path = format("%s-docker.pkg.dev/%s/%s", + var.region, module.orch-project.project_id, module.orch-artifact-reg.name) +} + +module "orch-project" { + source = "../../../modules/project" + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.orc : "${var.project_config.project_ids.orc}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.iam_orch : null + iam_additive = var.project_config.billing_account_id == null ? local.iam_orch : null + oslogin = false services = concat(var.project_services, [ "artifactregistry.googleapis.com", "bigquery.googleapis.com", @@ -132,11 +125,11 @@ module "orch-vpc" { source = "../../../modules/net-vpc" count = local.use_shared_vpc ? 0 : 1 project_id = module.orch-project.project_id - name = "${var.prefix}-default" + name = "${var.prefix}-orch" subnets = [ { ip_cidr_range = "10.10.0.0/24" - name = "default" + name = "${var.prefix}-orch" region = var.region secondary_ip_ranges = { pods = "10.10.8.0/22" @@ -160,7 +153,7 @@ module "orch-nat" { count = local.use_shared_vpc ? 0 : 1 source = "../../../modules/net-cloudnat" project_id = module.orch-project.project_id - name = "${var.prefix}-default" + name = "${var.prefix}-orch" region = var.region router_network = module.orch-vpc.0.name } diff --git a/blueprints/data-solutions/data-platform-foundations/04-transformation.tf b/blueprints/data-solutions/data-platform-foundations/04-transformation.tf index 3d3a818c57..394adedf8a 100644 --- a/blueprints/data-solutions/data-platform-foundations/04-transformation.tf +++ b/blueprints/data-solutions/data-platform-foundations/04-transformation.tf @@ -15,6 +15,19 @@ # tfdoc:file:description Trasformation project and VPC. locals { + iam_trf = { + "roles/bigquery.jobUser" = [ + module.transf-sa-bq-0.iam_email, local.groups_iam.data-engineers + ] + "roles/dataflow.admin" = [ + module.orch-sa-cmp-0.iam_email, local.groups_iam.data-engineers + ] + "roles/dataflow.worker" = [module.transf-sa-df-0.iam_email] + "roles/storage.objectAdmin" = [ + module.transf-sa-df-0.iam_email, + "serviceAccount:${module.transf-project.service_accounts.robots.dataflow}" + ] + } transf_subnet = ( local.use_shared_vpc ? var.network_config.subnet_self_links.orchestration @@ -29,31 +42,13 @@ locals { module "transf-project" { source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "trf${local.project_suffix}" - group_iam = { - (local.groups.data-engineers) = [ - "roles/bigquery.jobUser", - "roles/dataflow.admin", - ] - } - iam = { - "roles/bigquery.jobUser" = [ - module.transf-sa-bq-0.iam_email, - ] - "roles/dataflow.admin" = [ - module.orch-sa-cmp-0.iam_email, - ] - "roles/dataflow.worker" = [ - module.transf-sa-df-0.iam_email - ] - "roles/storage.objectAdmin" = [ - module.transf-sa-df-0.iam_email, - "serviceAccount:${module.transf-project.service_accounts.robots.dataflow}" - ] - } + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.trf : "${var.project_config.project_ids.trf}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.iam_trf : null + iam_additive = var.project_config.billing_account_id == null ? local.iam_trf : null services = concat(var.project_services, [ "bigquery.googleapis.com", "bigqueryreservation.googleapis.com", @@ -131,11 +126,11 @@ module "transf-vpc" { source = "../../../modules/net-vpc" count = local.use_shared_vpc ? 0 : 1 project_id = module.transf-project.project_id - name = "${var.prefix}-default" + name = "${var.prefix}-trf" subnets = [ { ip_cidr_range = "10.10.0.0/24" - name = "default" + name = "${var.prefix}-trf" region = var.region } ] @@ -155,7 +150,7 @@ module "transf-nat" { source = "../../../modules/net-cloudnat" count = local.use_shared_vpc ? 0 : 1 project_id = module.transf-project.project_id - name = "${var.prefix}-default" + name = "${var.prefix}-trf" region = var.region router_network = module.transf-vpc.0.name } diff --git a/blueprints/data-solutions/data-platform-foundations/05-datawarehouse.tf b/blueprints/data-solutions/data-platform-foundations/05-datawarehouse.tf index 0db5ce4404..67c43daefe 100644 --- a/blueprints/data-solutions/data-platform-foundations/05-datawarehouse.tf +++ b/blueprints/data-solutions/data-platform-foundations/05-datawarehouse.tf @@ -15,54 +15,48 @@ # tfdoc:file:description Data Warehouse projects. locals { - dwh_group_iam = { - (local.groups.data-engineers) = [ - "roles/bigquery.dataEditor", - "roles/storage.admin", - ], - (local.groups.data-analysts) = [ - "roles/bigquery.dataViewer", - "roles/bigquery.jobUser", - "roles/bigquery.metadataViewer", - "roles/bigquery.user", - "roles/datacatalog.viewer", - "roles/datacatalog.tagTemplateViewer", - "roles/storage.objectViewer", - ] - } dwh_lnd_iam = { "roles/bigquery.dataOwner" = [ module.load-sa-df-0.iam_email, + ] + "roles/bigquery.dataViewer" = [ module.transf-sa-df-0.iam_email, module.transf-sa-bq-0.iam_email, + local.groups_iam.data-engineers ] "roles/bigquery.jobUser" = [ - module.load-sa-df-0.iam_email, - ] - "roles/datacatalog.categoryAdmin" = [ - module.transf-sa-bq-0.iam_email - ] - "roles/storage.objectCreator" = [ - module.load-sa-df-0.iam_email, + module.load-sa-df-0.iam_email, local.groups_iam.data-engineers ] + "roles/datacatalog.categoryAdmin" = [module.transf-sa-bq-0.iam_email] + "roles/datacatalog.tagTemplateViewer" = [local.groups_iam.data-engineers] + "roles/datacatalog.viewer" = [local.groups_iam.data-engineers] + "roles/storage.objectCreator" = [module.load-sa-df-0.iam_email] + "roles/storage.objectViewer" = [local.groups_iam.data-engineers] } dwh_iam = { "roles/bigquery.dataOwner" = [ module.transf-sa-df-0.iam_email, module.transf-sa-bq-0.iam_email, ] + "roles/bigquery.dataViewer" = [ + local.groups_iam.data-analysts, + local.groups_iam.data-engineers + ] "roles/bigquery.jobUser" = [ module.transf-sa-bq-0.iam_email, + local.groups_iam.data-analysts, + local.groups_iam.data-engineers ] - "roles/datacatalog.categoryAdmin" = [ - module.load-sa-df-0.iam_email + "roles/datacatalog.tagTemplateViewer" = [ + local.groups_iam.data-analysts, local.groups_iam.data-engineers ] - "roles/storage.objectCreator" = [ - module.transf-sa-df-0.iam_email, + "roles/datacatalog.viewer" = [ + local.groups_iam.data-analysts, local.groups_iam.data-engineers ] "roles/storage.objectViewer" = [ - module.transf-sa-df-0.iam_email, + local.groups_iam.data-analysts, local.groups_iam.data-engineers ] + "roles/storage.objectAdmin" = [module.transf-sa-df-0.iam_email] } dwh_services = concat(var.project_services, [ "bigquery.googleapis.com", @@ -82,12 +76,13 @@ locals { module "dwh-lnd-project" { source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "dwh-lnd${local.project_suffix}" - group_iam = local.dwh_group_iam - iam = local.dwh_lnd_iam + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.dwh-lnd : "${var.project_config.project_ids.dwh-lnd}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.dwh_lnd_iam : {} + iam_additive = var.project_config.billing_account_id == null ? local.dwh_lnd_iam : {} services = local.dwh_services service_encryption_key_ids = { bq = [try(local.service_encryption_keys.bq, null)] @@ -97,12 +92,13 @@ module "dwh-lnd-project" { module "dwh-cur-project" { source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "dwh-cur${local.project_suffix}" - group_iam = local.dwh_group_iam - iam = local.dwh_iam + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.dwh-cur : "${var.project_config.project_ids.dwh-cur}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.dwh_iam : {} + iam_additive = var.project_config.billing_account_id == null ? local.dwh_iam : {} services = local.dwh_services service_encryption_key_ids = { bq = [try(local.service_encryption_keys.bq, null)] @@ -112,12 +108,13 @@ module "dwh-cur-project" { module "dwh-conf-project" { source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "dwh-conf${local.project_suffix}" - group_iam = local.dwh_group_iam - iam = local.dwh_iam + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.dwh-conf : "${var.project_config.project_ids.dwh-conf}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.dwh_iam : null + iam_additive = var.project_config.billing_account_id == null ? local.dwh_iam : null services = local.dwh_services service_encryption_key_ids = { bq = [try(local.service_encryption_keys.bq, null)] @@ -138,7 +135,7 @@ module "dwh-lnd-bq-0" { module "dwh-cur-bq-0" { source = "../../../modules/bigquery-dataset" project_id = module.dwh-cur-project.project_id - id = "${replace(var.prefix, "-", "_")}_dwh_lnd_bq_0" + id = "${replace(var.prefix, "-", "_")}_dwh_cur_bq_0" location = var.location encryption_key = try(local.service_encryption_keys.bq, null) } diff --git a/blueprints/data-solutions/data-platform-foundations/06-common.tf b/blueprints/data-solutions/data-platform-foundations/06-common.tf index 80451500c2..5a84ee777e 100644 --- a/blueprints/data-solutions/data-platform-foundations/06-common.tf +++ b/blueprints/data-solutions/data-platform-foundations/06-common.tf @@ -14,35 +14,22 @@ # tfdoc:file:description common project. -module "common-project" { - source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "cmn${local.project_suffix}" - group_iam = { - (local.groups.data-analysts) = [ - "roles/datacatalog.viewer", - ] - (local.groups.data-engineers) = [ - "roles/dlp.reader", - "roles/dlp.user", - "roles/dlp.estimatesAdmin", - ] - (local.groups.data-security) = [ - "roles/dlp.admin", - "roles/datacatalog.admin" - ] - } - iam = { +locals { + iam_common = { + "roles/dlp.admin" = [local.groups_iam.data-security] + "roles/dlp.estimatesAdmin" = [local.groups_iam.data-engineers] + "roles/dlp.reader" = [local.groups_iam.data-engineers] "roles/dlp.user" = [ module.load-sa-df-0.iam_email, - module.transf-sa-df-0.iam_email + module.transf-sa-df-0.iam_email, + local.groups_iam.data-engineers ] + "roles/datacatalog.admin" = [local.groups_iam.data-security] "roles/datacatalog.viewer" = [ module.load-sa-df-0.iam_email, module.transf-sa-df-0.iam_email, - module.transf-sa-bq-0.iam_email + module.transf-sa-bq-0.iam_email, + local.groups_iam.data-analysts ] "roles/datacatalog.categoryFineGrainedReader" = [ module.transf-sa-df-0.iam_email, @@ -51,6 +38,16 @@ module "common-project" { # local.groups_iam.data-analysts ] } +} +module "common-project" { + source = "../../../modules/project" + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.common : "${var.project_config.project_ids.common}${local.project_suffix}" + iam = var.project_config.billing_account_id != null ? local.iam_common : null + iam_additive = var.project_config.billing_account_id == null ? local.iam_common : null services = concat(var.project_services, [ "datacatalog.googleapis.com", "dlp.googleapis.com", diff --git a/blueprints/data-solutions/data-platform-foundations/07-exposure.tf b/blueprints/data-solutions/data-platform-foundations/07-exposure.tf index 030be0b832..ea8fca0947 100644 --- a/blueprints/data-solutions/data-platform-foundations/07-exposure.tf +++ b/blueprints/data-solutions/data-platform-foundations/07-exposure.tf @@ -16,8 +16,9 @@ module "exp-project" { source = "../../../modules/project" - parent = var.folder_id - billing_account = var.billing_account_id - prefix = var.prefix - name = "exp${local.project_suffix}" + parent = var.project_config.parent + billing_account = var.project_config.billing_account_id + project_create = var.project_config.billing_account_id != null + prefix = var.project_config.billing_account_id == null ? null : var.prefix + name = var.project_config.billing_account_id == null ? var.project_config.project_ids.exp : "${var.project_config.project_ids.exp}${local.project_suffix}" } diff --git a/blueprints/data-solutions/data-platform-foundations/IAM.md b/blueprints/data-solutions/data-platform-foundations/IAM.md index dd898bd750..b982f8c4ee 100644 --- a/blueprints/data-solutions/data-platform-foundations/IAM.md +++ b/blueprints/data-solutions/data-platform-foundations/IAM.md @@ -17,51 +17,48 @@ Legend: + additive, conditional. | members | roles | |---|---| -|gcp-data-engineers
group|[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/pubsub.editor](https://cloud.google.com/iam/docs/understanding-roles#pubsub.editor)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) | +|gcp-data-engineers
group|[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/bigquery.user](https://cloud.google.com/iam/docs/understanding-roles#bigquery.user) | |drp-bq-0
serviceAccount|[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor) | |drp-cs-0
serviceAccount|[roles/storage.objectCreator](https://cloud.google.com/iam/docs/understanding-roles#storage.objectCreator) | |drp-ps-0
serviceAccount|[roles/pubsub.publisher](https://cloud.google.com/iam/docs/understanding-roles#pubsub.publisher) | -|load-df-0
serviceAccount|[roles/bigquery.user](https://cloud.google.com/iam/docs/understanding-roles#bigquery.user)
[roles/pubsub.subscriber](https://cloud.google.com/iam/docs/understanding-roles#pubsub.subscriber)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | +|load-df-0
serviceAccount|[roles/bigquery.user](https://cloud.google.com/iam/docs/understanding-roles#bigquery.user)
[roles/pubsub.subscriber](https://cloud.google.com/iam/docs/understanding-roles#pubsub.subscriber)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | |orc-cmp-0
serviceAccount|[roles/pubsub.subscriber](https://cloud.google.com/iam/docs/understanding-roles#pubsub.subscriber)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | ## Project dwh-conf | members | roles | |---|---| -|gcp-data-analysts
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/bigquery.metadataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.metadataViewer)
[roles/bigquery.user](https://cloud.google.com/iam/docs/understanding-roles#bigquery.user)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | -|gcp-data-engineers
group|[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) | +|gcp-data-analysts
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | +|gcp-data-engineers
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | |SERVICE_IDENTITY_service-networking
serviceAccount|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) +| -|load-df-0
serviceAccount|[roles/datacatalog.categoryAdmin](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.categoryAdmin) | |trf-bq-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser) | -|trf-df-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/storage.objectCreator](https://cloud.google.com/iam/docs/understanding-roles#storage.objectCreator)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | +|trf-df-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | ## Project dwh-cur | members | roles | |---|---| -|gcp-data-analysts
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/bigquery.metadataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.metadataViewer)
[roles/bigquery.user](https://cloud.google.com/iam/docs/understanding-roles#bigquery.user)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | -|gcp-data-engineers
group|[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) | +|gcp-data-analysts
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | +|gcp-data-engineers
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | |SERVICE_IDENTITY_service-networking
serviceAccount|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) +| -|load-df-0
serviceAccount|[roles/datacatalog.categoryAdmin](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.categoryAdmin) | |trf-bq-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser) | -|trf-df-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/storage.objectCreator](https://cloud.google.com/iam/docs/understanding-roles#storage.objectCreator)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | +|trf-df-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | ## Project dwh-lnd | members | roles | |---|---| -|gcp-data-analysts
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/bigquery.metadataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.metadataViewer)
[roles/bigquery.user](https://cloud.google.com/iam/docs/understanding-roles#bigquery.user)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | -|gcp-data-engineers
group|[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin) | +|gcp-data-engineers
group|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/datacatalog.tagTemplateViewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.tagTemplateViewer)
[roles/datacatalog.viewer](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.viewer)
[roles/storage.objectViewer](https://cloud.google.com/iam/docs/understanding-roles#storage.objectViewer) | |SERVICE_IDENTITY_service-networking
serviceAccount|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) +| |load-df-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/storage.objectCreator](https://cloud.google.com/iam/docs/understanding-roles#storage.objectCreator) | -|trf-bq-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner)
[roles/datacatalog.categoryAdmin](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.categoryAdmin) | -|trf-df-0
serviceAccount|[roles/bigquery.dataOwner](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataOwner) | +|trf-bq-0
serviceAccount|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer)
[roles/datacatalog.categoryAdmin](https://cloud.google.com/iam/docs/understanding-roles#datacatalog.categoryAdmin) | +|trf-df-0
serviceAccount|[roles/bigquery.dataViewer](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataViewer) | ## Project lod | members | roles | |---|---| -|gcp-data-engineers
group|[roles/compute.viewer](https://cloud.google.com/iam/docs/understanding-roles#compute.viewer)
[roles/dataflow.admin](https://cloud.google.com/iam/docs/understanding-roles#dataflow.admin)
[roles/dataflow.developer](https://cloud.google.com/iam/docs/understanding-roles#dataflow.developer)
[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) | +|gcp-data-engineers
group|[roles/dataflow.admin](https://cloud.google.com/iam/docs/understanding-roles#dataflow.admin)
[roles/dataflow.developer](https://cloud.google.com/iam/docs/understanding-roles#dataflow.developer) | |SERVICE_IDENTITY_dataflow-service-producer-prod
serviceAccount|[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | |SERVICE_IDENTITY_service-networking
serviceAccount|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) +| |load-df-0
serviceAccount|[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/dataflow.admin](https://cloud.google.com/iam/docs/understanding-roles#dataflow.admin)
[roles/dataflow.worker](https://cloud.google.com/iam/docs/understanding-roles#dataflow.worker)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | @@ -71,7 +68,7 @@ Legend: + additive, conditional. | members | roles | |---|---| -|gcp-data-engineers
group|[roles/artifactregistry.admin](https://cloud.google.com/iam/docs/understanding-roles#artifactregistry.admin)
[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/cloudbuild.builds.editor](https://cloud.google.com/iam/docs/understanding-roles#cloudbuild.builds.editor)
[roles/composer.admin](https://cloud.google.com/iam/docs/understanding-roles#composer.admin)
[roles/composer.environmentAndStorageObjectAdmin](https://cloud.google.com/iam/docs/understanding-roles#composer.environmentAndStorageObjectAdmin)
[roles/iam.serviceAccountUser](https://cloud.google.com/iam/docs/understanding-roles#iam.serviceAccountUser)
[roles/iap.httpsResourceAccessor](https://cloud.google.com/iam/docs/understanding-roles#iap.httpsResourceAccessor)
[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer)
[roles/storage.admin](https://cloud.google.com/iam/docs/understanding-roles#storage.admin)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | +|gcp-data-engineers
group|[roles/artifactregistry.admin](https://cloud.google.com/iam/docs/understanding-roles#artifactregistry.admin)
[roles/bigquery.dataEditor](https://cloud.google.com/iam/docs/understanding-roles#bigquery.dataEditor)
[roles/bigquery.jobUser](https://cloud.google.com/iam/docs/understanding-roles#bigquery.jobUser)
[roles/cloudbuild.builds.editor](https://cloud.google.com/iam/docs/understanding-roles#cloudbuild.builds.editor)
[roles/composer.admin](https://cloud.google.com/iam/docs/understanding-roles#composer.admin)
[roles/composer.environmentAndStorageObjectAdmin](https://cloud.google.com/iam/docs/understanding-roles#composer.environmentAndStorageObjectAdmin)
[roles/iam.serviceAccountUser](https://cloud.google.com/iam/docs/understanding-roles#iam.serviceAccountUser)
[roles/iap.httpsResourceAccessor](https://cloud.google.com/iam/docs/understanding-roles#iap.httpsResourceAccessor)
[roles/serviceusage.serviceUsageConsumer](https://cloud.google.com/iam/docs/understanding-roles#serviceusage.serviceUsageConsumer)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | |SERVICE_IDENTITY_cloudcomposer-accounts
serviceAccount|[roles/composer.ServiceAgentV2Ext](https://cloud.google.com/iam/docs/understanding-roles#composer.ServiceAgentV2Ext)
[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | |SERVICE_IDENTITY_gcp-sa-cloudbuild
serviceAccount|[roles/storage.objectAdmin](https://cloud.google.com/iam/docs/understanding-roles#storage.objectAdmin) | |SERVICE_IDENTITY_service-networking
serviceAccount|[roles/servicenetworking.serviceAgent](https://cloud.google.com/iam/docs/understanding-roles#servicenetworking.serviceAgent) +| diff --git a/blueprints/data-solutions/data-platform-foundations/README.md b/blueprints/data-solutions/data-platform-foundations/README.md index 08b24b2116..5f41e0de31 100644 --- a/blueprints/data-solutions/data-platform-foundations/README.md +++ b/blueprints/data-solutions/data-platform-foundations/README.md @@ -213,13 +213,15 @@ While this blueprint can be used as a standalone deployment, it can also be call ```hcl module "data-platform" { source = "./fabric/blueprints/data-solutions/data-platform-foundations" - billing_account_id = var.billing_account_id - folder_id = var.folder_id organization_domain = "example.com" - prefix = "myprefix" + project_config = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + prefix = "myprefix" } -# tftest modules=43 resources=297 +# tftest modules=43 resources=278 ``` ## Customizations @@ -233,6 +235,14 @@ To create Cloud Key Management keys in the Data Platform you can uncomment the C To handle multiple groups of `data-analysts` accessing the same Data Warehouse layer projects but only to the dataset belonging to a specific group, you may want to assign roles at BigQuery dataset level instead of at project-level. To do this, you need to remove IAM binging at project-level for the `data-analysts` group and give roles at BigQuery dataset level using the `iam` variable on `bigquery-dataset` modules. +### Project Configuration + +The solution can be deployed by creating projects on a given parent (organization or folder) or on existing projects. Configure variable `project_config` accordingly. + +When you rely on existing projects, the blueprint is designed to rely on different projects configuring IAM binding with an additive approach. For discovery or experimentation purposes, you may also configure `project_config.project_ids` to point different projects to one project with the granularity you need. For example, deploy resources from the 'load' project with resources in the 'transformation' project. + +Once you have identified the required project granularity for your use case, we suggest adapting the terraform script accordingly and relying on authoritative IAM binding. + ## Demo pipeline The application layer is out of scope of this script. As a demo purpuse only, several Cloud Composer DAGs are provided. Demos will import data from the `drop off` area to the `Data Warehouse Confidential` dataset suing different features. @@ -244,20 +254,19 @@ You can find examples in the `[demo](./demo)` folder. | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [billing_account_id](variables.tf#L17) | Billing account id. | string | ✓ | | -| [folder_id](variables.tf#L122) | Folder to be used for the networking resources in folders/nnnn format. | string | ✓ | | -| [organization_domain](variables.tf#L166) | Organization domain. | string | ✓ | | -| [prefix](variables.tf#L171) | Prefix used for resource names. | string | ✓ | | -| [composer_config](variables.tf#L22) | Cloud Composer config. | object({…}) | | {…} | -| [data_catalog_tags](variables.tf#L105) | List of Data Catalog Policy tags to be created with optional IAM binging configuration in {tag => {ROLE => [MEMBERS]}} format. | map(map(list(string))) | | {…} | -| [data_force_destroy](variables.tf#L116) | Flag to set 'force_destroy' on data services like BiguQery or Cloud Storage. | bool | | false | -| [groups](variables.tf#L127) | User groups. | map(string) | | {…} | -| [location](variables.tf#L137) | Location used for multi-regional resources. | string | | "eu" | -| [network_config](variables.tf#L143) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | object({…}) | | null | -| [project_services](variables.tf#L180) | List of core services enabled on all projects. | list(string) | | […] | -| [project_suffix](variables.tf#L191) | Suffix used only for project ids. | string | | null | -| [region](variables.tf#L197) | Region used for regional resources. | string | | "europe-west1" | -| [service_encryption_keys](variables.tf#L203) | Cloud KMS to use to encrypt different services. Key location should match service region. | object({…}) | | null | +| [organization_domain](variables.tf#L156) | Organization domain. | string | ✓ | | +| [prefix](variables.tf#L161) | Prefix used for resource names. | string | ✓ | | +| [project_config](variables.tf#L170) | Provide 'billing_account_id' value if project creation is needed, uses existing 'project_ids' if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | object({…}) | ✓ | | +| [composer_config](variables.tf#L17) | Cloud Composer config. | object({…}) | | {…} | +| [data_catalog_tags](variables.tf#L100) | List of Data Catalog Policy tags to be created with optional IAM binging configuration in {tag => {ROLE => [MEMBERS]}} format. | map(map(list(string))) | | {…} | +| [data_force_destroy](variables.tf#L111) | Flag to set 'force_destroy' on data services like BiguQery or Cloud Storage. | bool | | false | +| [groups](variables.tf#L117) | User groups. | map(string) | | {…} | +| [location](variables.tf#L127) | Location used for multi-regional resources. | string | | "eu" | +| [network_config](variables.tf#L133) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | object({…}) | | null | +| [project_services](variables.tf#L204) | List of core services enabled on all projects. | list(string) | | […] | +| [project_suffix](variables.tf#L215) | Suffix used only for project ids. | string | | null | +| [region](variables.tf#L221) | Region used for regional resources. | string | | "europe-west1" | +| [service_encryption_keys](variables.tf#L227) | Cloud KMS to use to encrypt different services. Key location should match service region. | object({…}) | | null | ## Outputs @@ -280,3 +289,18 @@ Features to add in future releases: - Add example on how to use Cloud Data Loss Prevention - Add solution to handle Tables, Views, and Authorized Views lifecycle - Add solution to handle Metadata lifecycle + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/data-platform-foundations/" + organization_domain = "example.com" + project_config = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + prefix = "prefix" +} +# tftest modules=43 resources=278 +``` diff --git a/blueprints/data-solutions/data-platform-foundations/demo/dataflow-csv2bq/README.md b/blueprints/data-solutions/data-platform-foundations/demo/dataflow-csv2bq/README.md index 44f178fa26..b052fab058 100644 --- a/blueprints/data-solutions/data-platform-foundations/demo/dataflow-csv2bq/README.md +++ b/blueprints/data-solutions/data-platform-foundations/demo/dataflow-csv2bq/README.md @@ -3,7 +3,66 @@ This demo serves as a simple example of building and launching a Flex Template D ![Dataflow pipeline overview](../../images/df_demo_pipeline.png "Dataflow pipeline overview") -## Example build run + +## Local development run + +For local development, the pipeline can be launched from the local machine for testing purposes using different runners depending on the scope of the test. + +### Using the Beam DirectRunner +The below example uses the Beam DirectRunner. The use case for this runner is mainly for quick local tests on the development environment with low volume of data. + +``` +CSV_FILE=gs://[TEST-BUCKET]/customers.csv +JSON_SCHEMA=gs://[TEST-BUCKET]/customers_schema.json +OUTPUT_TABLE=[TEST-PROJ].[TEST-DATASET].customers +PIPELINE_STAGIN_PATH="gs://[TEST-STAGING-BUCKET]" + +python src/csv2bq.py \ +--runner="DirectRunner" \ +--csv_file=$CSV_FILE \ +--json_schema=$JSON_SCHEMA \ +--output_table=$OUTPUT_TABLE \ +--temp_location=$PIPELINE_STAGIN_PATH/tmp +``` + +*Note:* All paths mentioned can be local paths or on GCS. For cloud resources referenced (GCS and BigQuery), make sure that the user launching the command is authenticated to GCP via `gcloud auth application-default login` and has the required access privileges to those resources. + +### Using the DataflowRunner with a local CLI launch + +The below example triggers the pipeline on Dataflow from your local development environment. The use case for this is for running local tests on larger volumes of test data and verifying that the pipeline runs well on Dataflow, before compiling it into a template. + +``` +PROJECT_ID=[TEST-PROJECT] +REGION=[REGION] +SUBNET=[SUBNET-NAME] +DEV_SERVICE_ACCOUNT=[DEV-SA] + +PIPELINE_STAGIN_PATH="gs://[TEST-STAGING-BUCKET]" +CSV_FILE=gs://[TEST-BUCKET]/customers.csv +JSON_SCHEMA=gs://[TEST-BUCKET]/customers_schema.json +OUTPUT_TABLE=[TEST-PROJ].[TEST-DATASET].customers + +python src/csv2bq.py \ +--runner="Dataflow" \ +--project=$PROJECT_ID \ +--region=$REGION \ +--csv_file=$CSV_FILE \ +--json_schema=$JSON_SCHEMA \ +--output_table=$OUTPUT_TABLE \ +--temp_location=$PIPELINE_STAGIN_PATH/tmp +--staging_location=$PIPELINE_STAGIN_PATH/stage \ +--subnetwork="regions/$REGION/subnetworks/$SUBNET" \ +--impersonate_service_account=$DEV_SERVICE_ACCOUNT \ +--no_use_public_ips +``` + +In terms of resource access privilege, you can choose to impersonate another service account, which could be defined for development resource access. The authenticated user launching this pipeline will need to have the role `roles/iam.serviceAccountTokenCreator`. If you choose to launch the pipeline without service account impersonation, it will use the default compute service account assigned of the target project. + +## Dataflow Flex Template run + +For production, and as outline in the Data Platform demo, we build and launch the pipeline as a Flex Template, making it available for other cloud services(such as Apache Airflow) and users to trigger launch instances of it on demand. + +### Build launch Below is an example for triggering the Dataflow flex template build pipeline defined in `cloudbuild.yaml`. The Terraform output provides an example as well filled with the parameters values based on the generated resources in the data platform. @@ -28,9 +87,9 @@ gcloud builds submit \ **Note:** For the scope of the demo, the launch of this build is manual, but in production, this build would be launched via a configured cloud build trigger when new changes are merged into the code branch of the Dataflow template. -## Example Dataflow pipeline launch in bash (from flex template) +### Dataflow Flex Template run -Below is an example of launching a dataflow pipeline manually, based on the built template. When launched manually, the Dataflow pipeline would be launched via the orchestration service account, which is what the Airflow DAG is also using in the scope of this demo. +After the build step succeeds. You can launch dataflow pipeline from CLI (outline in this example) or the API via Airflow's operator. For the use case of the data platform, the Dataflow pipeline would be launched via the orchestration service account, which is what the Airflow DAG is also using in the scope of this demo. **Note:** In the data platform demo, the launch of this Dataflow pipeline is handled by the airflow operator (DataflowStartFlexTemplateOperator). diff --git a/blueprints/data-solutions/data-platform-foundations/demo/datapipeline_dc_tags.py b/blueprints/data-solutions/data-platform-foundations/demo/datapipeline_dc_tags.py index 4b15eaaba5..86b8e5bbe6 100644 --- a/blueprints/data-solutions/data-platform-foundations/demo/datapipeline_dc_tags.py +++ b/blueprints/data-solutions/data-platform-foundations/demo/datapipeline_dc_tags.py @@ -123,7 +123,7 @@ task_id="upsert_table_customers", project_id=DWH_LAND_PRJ, dataset_id=DWH_LAND_BQ_DATASET, - impersonation_chain=[TRF_SA_DF], + impersonation_chain=[LOD_SA_DF], table_resource={ "tableReference": {"tableId": "customers"}, }, @@ -133,7 +133,7 @@ task_id="upsert_table_purchases", project_id=DWH_LAND_PRJ, dataset_id=DWH_LAND_BQ_DATASET, - impersonation_chain=[TRF_SA_BQ], + impersonation_chain=[LOD_SA_DF], table_resource={ "tableReference": {"tableId": "purchases"} }, @@ -167,7 +167,7 @@ project_id=DWH_LAND_PRJ, dataset_id=DWH_LAND_BQ_DATASET, table_id="customers", - impersonation_chain=[TRF_SA_BQ], + impersonation_chain=[LOD_SA_DF], include_policy_tags=True, schema_fields_updates=[ { "mode": "REQUIRED", "name": "id", "type": "INTEGER", "description": "ID" }, @@ -182,7 +182,7 @@ project_id=DWH_LAND_PRJ, dataset_id=DWH_LAND_BQ_DATASET, table_id="purchases", - impersonation_chain=[TRF_SA_BQ], + impersonation_chain=[LOD_SA_DF], include_policy_tags=True, schema_fields_updates=[ { "mode": "REQUIRED", "name": "id", "type": "INTEGER", "description": "ID" }, diff --git a/blueprints/data-solutions/data-platform-foundations/demo/delete_table.py b/blueprints/data-solutions/data-platform-foundations/demo/delete_table.py index dc0c954b14..bade038871 100644 --- a/blueprints/data-solutions/data-platform-foundations/demo/delete_table.py +++ b/blueprints/data-solutions/data-platform-foundations/demo/delete_table.py @@ -122,13 +122,13 @@ delete_table_customers = BigQueryDeleteTableOperator( task_id="delete_table_customers", deletion_dataset_table=DWH_LAND_PRJ+"."+DWH_LAND_BQ_DATASET+".customers", - impersonation_chain=[TRF_SA_DF] + impersonation_chain=[LOD_SA_DF] ) delete_table_purchases = BigQueryDeleteTableOperator( task_id="delete_table_purchases", deletion_dataset_table=DWH_LAND_PRJ+"."+DWH_LAND_BQ_DATASET+".purchases", - impersonation_chain=[TRF_SA_DF] + impersonation_chain=[LOD_SA_DF] ) delete_table_customer_purchase_curated = BigQueryDeleteTableOperator( diff --git a/blueprints/data-solutions/data-platform-foundations/variables.tf b/blueprints/data-solutions/data-platform-foundations/variables.tf index 6c25406a2f..4ec2fd7e1f 100644 --- a/blueprints/data-solutions/data-platform-foundations/variables.tf +++ b/blueprints/data-solutions/data-platform-foundations/variables.tf @@ -14,11 +14,6 @@ # tfdoc:file:description Terraform Variables. -variable "billing_account_id" { - description = "Billing account id." - type = string -} - variable "composer_config" { description = "Cloud Composer config." type = object({ @@ -119,11 +114,6 @@ variable "data_force_destroy" { default = false } -variable "folder_id" { - description = "Folder to be used for the networking resources in folders/nnnn format." - type = string -} - variable "groups" { description = "User groups." type = map(string) @@ -177,6 +167,40 @@ variable "prefix" { } } +variable "project_config" { + description = "Provide 'billing_account_id' value if project creation is needed, uses existing 'project_ids' if null. Parent is in 'folders/nnn' or 'organizations/nnn' format." + type = object({ + billing_account_id = optional(string, null) + parent = string + project_ids = optional(object({ + drop = string + load = string + orc = string + trf = string + dwh-lnd = string + dwh-cur = string + dwh-conf = string + common = string + exp = string + }), { + drop = "drp" + load = "lod" + orc = "orc" + trf = "trf" + dwh-lnd = "dwh-lnd" + dwh-cur = "dwh-cur" + dwh-conf = "dwh-conf" + common = "cmn" + exp = "exp" + } + ) + }) + validation { + condition = var.project_config.billing_account_id != null || var.project_config.project_ids != null + error_message = "At least one attribute should be set." + } +} + variable "project_services" { description = "List of core services enabled on all projects." type = list(string) diff --git a/blueprints/data-solutions/data-playground/README.md b/blueprints/data-solutions/data-playground/README.md index db7d51fce0..2e71944505 100644 --- a/blueprints/data-solutions/data-playground/README.md +++ b/blueprints/data-solutions/data-playground/README.md @@ -68,3 +68,18 @@ You can now connect to the Vertex AI notbook to perform your data analysy. | [vpc](outputs.tf#L38) | VPC Network. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/data-playground" + project_id = "sampleproject" + prefix = "tst" + project_create = { + billing_account_id = "123456-123456-123456", + parent = "folders/467898377" + } +} +# tftest modules=8 resources=39 +``` diff --git a/blueprints/data-solutions/data-playground/main.tf b/blueprints/data-solutions/data-playground/main.tf index b87e8e7301..a3cfd54eb6 100644 --- a/blueprints/data-solutions/data-playground/main.tf +++ b/blueprints/data-solutions/data-playground/main.tf @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -83,8 +83,8 @@ module "project" { } org_policies = { - # "constraints/compute.requireOsLogin" = { - # enforce = false + # "compute.requireOsLogin" = { + # rules = [{ enforce = false }] # } # Example of applying a project wide policy, mainly useful for Composer 1 } @@ -217,6 +217,11 @@ resource "google_notebooks_instance" "playground" { service_account = module.service-account-notebook.email + # Remove once terraform-provider-google/issues/9164 is fixed + lifecycle { + ignore_changes = [disk_encryption, kms_key] + } + #TODO Uncomment once terraform-provider-google/issues/9273 is fixed # tags = ["ssh"] depends_on = [ diff --git a/blueprints/data-solutions/data-playground/versions.tf b/blueprints/data-solutions/data-playground/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/data-solutions/data-playground/versions.tf +++ b/blueprints/data-solutions/data-playground/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/data-solutions/gcs-to-bq-with-least-privileges/README.md b/blueprints/data-solutions/gcs-to-bq-with-least-privileges/README.md index 54f47ecab5..eefb5e868c 100644 --- a/blueprints/data-solutions/gcs-to-bq-with-least-privileges/README.md +++ b/blueprints/data-solutions/gcs-to-bq-with-least-privileges/README.md @@ -215,3 +215,18 @@ The above command will delete the associated resources so there will be no billa | [service_accounts](outputs.tf#L69) | Service account. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/gcs-to-bq-with-least-privileges/" + project_create = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + project_id = "project-1" + prefix = "prefix" +} +# tftest modules=12 resources=47 +``` diff --git a/blueprints/data-solutions/gcs-to-bq-with-least-privileges/versions.tf b/blueprints/data-solutions/gcs-to-bq-with-least-privileges/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/data-solutions/gcs-to-bq-with-least-privileges/versions.tf +++ b/blueprints/data-solutions/gcs-to-bq-with-least-privileges/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/data-solutions/shielded-folder/README.md b/blueprints/data-solutions/shielded-folder/README.md index aaf67e6acd..5496eaa74b 100644 --- a/blueprints/data-solutions/shielded-folder/README.md +++ b/blueprints/data-solutions/shielded-folder/README.md @@ -178,3 +178,33 @@ terraform apply | [folders_sink_writer_identities](outputs.tf#L23) | Folders id. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/shielded-folder" + data_dir = "./fabric/blueprints/data-solutions/shielded-folder/data" + access_policy_config = { + access_policy_create = { + parent = "organizations/1234567890123" + title = "ShieldedMVP" + } + } + folder_config = { + folder_create = { + display_name = "ShieldedMVP" + parent = "organizations/1234567890123" + } + } + organization = { + domain = "example.com" + id = "1122334455" + } + prefix = "prefix" + project_config = { + billing_account_id = "123456-123456-123456" + } +} +# tftest modules=6 resources=38 inventory=simple.yaml +``` diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml index 0d27ac426d..a3f96b1b1c 100644 --- a/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/compute.yaml @@ -3,71 +3,90 @@ # sample subset of useful organization policies, edit to suit requirements compute.disableGuestAttributesAccess: - enforce: true + rules: + - enforce: true compute.requireOsLogin: - enforce: true + rules: + - enforce: true compute.restrictLoadBalancerCreationForTypes: - allow: - values: - - in:INTERNAL + rules: + - allow: + values: + - in:INTERNAL compute.skipDefaultNetworkCreation: - enforce: true + rules: + - enforce: true compute.vmExternalIpAccess: - deny: - all: true + rules: + - deny: + all: true # compute.disableInternetNetworkEndpointGroup: -# enforce: true +# rules: +# - enforce: true # compute.disableNestedVirtualization: -# enforce: true +# rules: +# - enforce: true # compute.disableSerialPortAccess: -# enforce: true +# rules: +# - enforce: true # compute.restrictCloudNATUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictDedicatedInterconnectUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictPartnerInterconnectUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictProtocolForwardingCreationForTypes: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictSharedVpcHostProjects: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictSharedVpcSubnetworks: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictVpcPeering: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictVpnPeerIPs: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictXpnProjectLienRemoval: -# enforce: true +# rules: +# - enforce: true # compute.setNewProjectDefaultToZonalDNSOnly: -# enforce: true +# rules: +# - enforce: true # compute.vmCanIpForward: -# deny: -# all: true +# rules: +# - deny: +# all: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml index 4d83f827fe..58e0032cb3 100644 --- a/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/iam.yaml @@ -3,10 +3,13 @@ # sample subset of useful organization policies, edit to suit requirements iam.automaticIamGrantsForDefaultServiceAccounts: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyCreation: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyUpload: - enforce: true + rules: + - enforce: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml index de62e6c702..3efb23cdee 100644 --- a/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/serverless.yaml @@ -3,24 +3,29 @@ # sample subset of useful organization policies, edit to suit requirements run.allowedIngress: - allow: - values: - - is:internal + rules: + - allow: + values: + - is:internal # run.allowedVPCEgress: -# allow: -# values: +# rules: +# - allow: +# values: # - is:private-ranges-only # cloudfunctions.allowedIngressSettings: -# allow: -# values: -# - is:ALLOW_INTERNAL_ONLY +# rules: +# - allow: +# values: +# - is:ALLOW_INTERNAL_ONLY # cloudfunctions.allowedVpcConnectorEgressSettings: -# allow: -# values: -# - is:PRIVATE_RANGES_ONLY +# rules: +# - allow: +# values: +# - is:PRIVATE_RANGES_ONLY # cloudfunctions.requireVPCConnector: -# enforce: true +# rules: +# - enforce: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml index 88b84d9d50..0eee80453a 100644 --- a/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/sql.yaml @@ -3,7 +3,9 @@ # sample subset of useful organization policies, edit to suit requirements sql.restrictAuthorizedNetworks: - enforce: true + rules: + - enforce: true sql.restrictPublicIp: - enforce: true + rules: + - enforce: true diff --git a/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml b/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml index 6c0a673f3a..448357b8bc 100644 --- a/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml +++ b/blueprints/data-solutions/shielded-folder/data/org-policies/storage.yaml @@ -3,4 +3,5 @@ # sample subset of useful organization policies, edit to suit requirements storage.uniformBucketLevelAccess: - enforce: true + rules: + - enforce: true diff --git a/blueprints/data-solutions/sqlserver-alwayson/README.md b/blueprints/data-solutions/sqlserver-alwayson/README.md index 1ce4dad7d4..695c8f0bbc 100644 --- a/blueprints/data-solutions/sqlserver-alwayson/README.md +++ b/blueprints/data-solutions/sqlserver-alwayson/README.md @@ -69,3 +69,23 @@ and to `C:\GcpSetupLog.txt` file. | [instructions](outputs.tf#L19) | List of steps to follow after applying. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/sqlserver-alwayson/" + project_create = { + billing_account_id = "123456-123456-123456" + parent = "folders/12345678" + } + project_id = "project-1" + prefix = "test" + network = "example-network" + subnetwork = "example-subnetwork" + sql_admin_password = "password" + ad_domain_fqdn = "ad.example.com" + ad_domain_netbios = "ad" +} +# tftest modules=12 resources=38 +``` diff --git a/blueprints/data-solutions/vertex-mlops/README.md b/blueprints/data-solutions/vertex-mlops/README.md index d9f85fd837..8bb3043ed6 100644 --- a/blueprints/data-solutions/vertex-mlops/README.md +++ b/blueprints/data-solutions/vertex-mlops/README.md @@ -74,6 +74,36 @@ This blueprint can be used as a building block for setting up an end2end ML Ops | [project_id](outputs.tf#L49) | Project ID. | | -# TODO + +## TODO - Add support for User Managed Notebooks, SA permission option and non default SA for Single User mode. -- Improve default naming for local VPC and Cloud NAT \ No newline at end of file +- Improve default naming for local VPC and Cloud NAT + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/data-solutions/vertex-mlops/" + labels = { + "env" : "dev", + "team" : "ml" + } + bucket_name = "test-dev" + dataset_name = "test" + identity_pool_claims = "attribute.repository/ORGANIZATION/REPO" + notebooks = { + "myworkbench" : { + "owner" : "user@example.com", + "region" : "europe-west4", + "subnet" : "default", + } + } + prefix = "pref" + project_id = "test-dev" + project_create = { + billing_account_id = "000000-123456-123456" + parent = "folders/111111111111" + } +} +# tftest modules=12 resources=56 +``` diff --git a/blueprints/data-solutions/vertex-mlops/main.tf b/blueprints/data-solutions/vertex-mlops/main.tf index 5f7fbc0c97..27129298af 100644 --- a/blueprints/data-solutions/vertex-mlops/main.tf +++ b/blueprints/data-solutions/vertex-mlops/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -112,7 +112,7 @@ module "gcs-bucket" { encryption_key = try(local.service_encryption_keys.storage, null) } -# Default bucket for Cloud Build to prevent error: "'us' violates constraint ‘constraints/gcp.resourceLocations’" +# Default bucket for Cloud Build to prevent error: "'us' violates constraint ‘gcp.resourceLocations’" # https://stackoverflow.com/questions/53206667/cloud-build-fails-with-resource-location-constraint module "gcs-bucket-cloudbuild" { source = "../../../modules/gcs" @@ -230,8 +230,8 @@ module "project" { org_policies = { # Example of applying a project wide policy - # "constraints/compute.requireOsLogin" = { - # enforce = false + # "compute.requireOsLogin" = { + # rules = [{ enforce = false }] # } } diff --git a/blueprints/factories/bigquery-factory/README.md b/blueprints/factories/bigquery-factory/README.md index 2cba6e01f9..1e3015ed6d 100644 --- a/blueprints/factories/bigquery-factory/README.md +++ b/blueprints/factories/bigquery-factory/README.md @@ -71,6 +71,7 @@ module "bq" { | [views_path](variables.tf#L27) | Relative path for the folder storing view data. | string | ✓ | | + ## TODO - [ ] add external table support diff --git a/blueprints/factories/cloud-identity-group-factory/README.md b/blueprints/factories/cloud-identity-group-factory/README.md index b833304eb2..318eea2578 100644 --- a/blueprints/factories/cloud-identity-group-factory/README.md +++ b/blueprints/factories/cloud-identity-group-factory/README.md @@ -9,13 +9,22 @@ Yaml abstraction for Groups can simplify groups creation and members management. ### Terraform code ```hcl -module "prod-firewall" { - source = "./fabric/blueprints/factories/cloud-identity-group-factory" - +module "groups" { + source = "./fabric/blueprints/factories/cloud-identity-group-factory" customer_id = "customers/C0xxxxxxx" data_dir = "data" } -# tftest skip +# tftest modules=2 resources=3 files=group1 inventory=example.yaml +``` + +```yaml +# tftest-file id=group1 path=data/group1@example.com.yaml +display_name: Group 1 +description: Group 1 +members: + - user1@example.com +managers: + - user2@example.com ``` ### Configuration Structure diff --git a/blueprints/factories/net-vpc-firewall-yaml/README.md b/blueprints/factories/net-vpc-firewall-yaml/README.md index 5e7260e942..42cd6fad9f 100644 --- a/blueprints/factories/net-vpc-firewall-yaml/README.md +++ b/blueprints/factories/net-vpc-firewall-yaml/README.md @@ -17,8 +17,8 @@ module "prod-firewall" { project_id = "my-prod-project" network = "my-prod-network" config_directories = [ - "./prod", - "./common" + "./firewall/prod", + "./firewall/common" ] log_config = { @@ -32,13 +32,86 @@ module "dev-firewall" { project_id = "my-dev-project" network = "my-dev-network" config_directories = [ - "./dev", - "./common" + "./firewall/dev", + "./firewall/common" ] } -# tftest skip +# tftest modules=2 resources=16 files=common,dev,prod inventory=example.yaml ``` +```yaml +# tftest-file id=common path=firewall/common/common.yaml +# allow ingress from GCLB to all instances in the network +lb-health-checks: + allow: + - ports: [] + protocol: tcp + direction: INGRESS + priority: 1001 + source_ranges: + - 35.191.0.0/16 + - 130.211.0.0/22 + +# deny all egress +deny-all: + deny: + - ports: [] + protocol: all + direction: EGRESS + priority: 65535 + destination_ranges: + - 0.0.0.0/0 +``` + +```yaml +# tftest-file id=dev path=firewall/dev/app.yaml +# Myapp egress +web-app-dev-egress: + allow: + - ports: [443] + protocol: tcp + direction: EGRESS + destination_ranges: + - 192.168.0.0/24 + target_service_accounts: + - myapp@myproject-dev.iam.gserviceaccount.com +# Myapp ingress +web-app-dev-ingress: + allow: + - ports: [1234] + protocol: tcp + direction: INGRESS + source_service_accounts: + - frontend-sa@myproject-dev.iam.gserviceaccount.com + target_service_accounts: + - web-app-a@myproject-dev.iam.gserviceaccount.com +``` + +```yaml +# tftest-file id=prod path=firewall/prod/app.yaml +# Myapp egress +web-app-prod-egress: + allow: + - ports: [443] + protocol: tcp + direction: EGRESS + destination_ranges: + - 192.168.10.0/24 + target_service_accounts: + - myapp@myproject-prod.iam.gserviceaccount.com +# Myapp ingress +web-app-prod-ingress: + allow: + - ports: [1234] + protocol: tcp + direction: INGRESS + source_service_accounts: + - frontend-sa@myproject-prod.iam.gserviceaccount.com + target_service_accounts: + - web-app-a@myproject-prod.iam.gserviceaccount.com +``` + + ### Configuration Structure ```bash @@ -86,54 +159,6 @@ rule-name: # descriptive name, naming convention is adjusted by the module - myapp@myproject-id.iam.gserviceaccount.com ``` - -Firewall rules example yaml configuration - -```bash -cat ./prod/core-network/common-rules.yaml -# allow ingress from GCLB to all instances in the network -lb-health-checks: - allow: - - ports: [] - protocol: tcp - direction: INGRESS - priority: 1001 - source_ranges: - - 35.191.0.0/16 - - 130.211.0.0/22 - -# deny all egress -deny-all: - deny: - - ports: [] - protocol: all - direction: EGRESS - priority: 65535 - destination_ranges: - - 0.0.0.0/0 - -cat ./dev/team-a/web-app-a.yaml -# Myapp egress -web-app-a-egress: - allow: - - ports: [443] - protocol: tcp - direction: EGRESS - destination_ranges: - - 192.168.0.0/24 - target_service_accounts: - - myapp@myproject-id.iam.gserviceaccount.com -# Myapp ingress -web-app-a-ingress: - allow: - - ports: [1234] - protocol: tcp - direction: INGRESS - source_service_accounts: - - frontend-sa@myproject-id.iam.gserviceaccount.com - target_service_accounts: - - web-app-a@myproject-id.iam.gserviceaccount.com -``` ## Variables diff --git a/blueprints/factories/net-vpc-firewall-yaml/main.tf b/blueprints/factories/net-vpc-firewall-yaml/main.tf index d478625c2d..90416faaeb 100644 --- a/blueprints/factories/net-vpc-firewall-yaml/main.tf +++ b/blueprints/factories/net-vpc-firewall-yaml/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -20,8 +20,8 @@ locals { for config_path in var.config_directories : concat( [ - for config_file in fileset("${path.root}/${config_path}", "**/*.yaml") : - "${path.root}/${config_path}/${config_file}" + for config_file in fileset(config_path, "**/*.yaml") : + "${config_path}/${config_file}" ] ) diff --git a/blueprints/factories/net-vpc-firewall-yaml/versions.tf b/blueprints/factories/net-vpc-firewall-yaml/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/factories/net-vpc-firewall-yaml/versions.tf +++ b/blueprints/factories/net-vpc-firewall-yaml/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/factories/project-factory/README.md b/blueprints/factories/project-factory/README.md index 2b8c3874e6..a86e708e30 100644 --- a/blueprints/factories/project-factory/README.md +++ b/blueprints/factories/project-factory/README.md @@ -76,7 +76,7 @@ module "projects" { service_identities_iam = try(each.value.service_identities_iam, {}) vpc = try(each.value.vpc, null) } -# tftest modules=7 resources=29 +# tftest modules=7 resources=30 inventory=example.yaml ``` ### Projects configuration @@ -156,15 +156,18 @@ labels: # [opt] Org policy overrides defined at project level org_policies: - constraints/compute.disableGuestAttributesAccess: - enforce: true - constraints/compute.trustedImageProjects: - allow: - values: + compute.disableGuestAttributesAccess: + rules: + - enforce: true + compute.trustedImageProjects: + rules: + - allow: + values: - projects/fast-dev-iac-core-0 - constraints/compute.vmExternalIpAccess: - deny: - all: true + compute.vmExternalIpAccess: + rules: + - deny: + all: true # [opt] Service account to create for the project and their roles on the project # in name => [roles] format @@ -223,8 +226,8 @@ vpc: | name | description | type | required | default | |---|---|:---:|:---:|:---:| | [billing_account_id](variables.tf#L17) | Billing account id. | string | ✓ | | -| [prefix](variables.tf#L157) | Prefix used for resource names. | string | ✓ | | -| [project_id](variables.tf#L166) | Project id. | string | ✓ | | +| [prefix](variables.tf#L144) | Prefix used for resource names. | string | ✓ | | +| [project_id](variables.tf#L153) | Project id. | string | ✓ | | | [billing_alert](variables.tf#L22) | Billing alert configuration. | object({…}) | | null | | [defaults](variables.tf#L35) | Project factory default values. | object({…}) | | null | | [descriptive_name](variables.tf#L57) | Name of the project name. Used for project name instead of `name` variable. | string | | null | @@ -237,15 +240,15 @@ vpc: | [iam_additive](variables.tf#L99) | Custom additive IAM settings in role => [principal] format. | map(list(string)) | | {} | | [kms_service_agents](variables.tf#L105) | KMS IAM configuration in as service => [key]. | map(list(string)) | | {} | | [labels](variables.tf#L111) | Labels to be assigned at project level. | map(string) | | {} | -| [org_policies](variables.tf#L117) | Org-policy overrides at project level. | map(object({…})) | | {} | -| [service_accounts](variables.tf#L171) | Service accounts to be created, and roles assigned them on the project. | map(list(string)) | | {} | -| [service_accounts_additive](variables.tf#L177) | Service accounts to be created, and roles assigned them on the project additively. | map(list(string)) | | {} | -| [service_accounts_iam](variables.tf#L183) | IAM bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]}. | map(map(list(string))) | | {} | -| [service_accounts_iam_additive](variables.tf#L190) | IAM additive bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]}. | map(map(list(string))) | | {} | -| [service_identities_iam](variables.tf#L197) | Custom IAM settings for service identities in service => [role] format. | map(list(string)) | | {} | -| [service_identities_iam_additive](variables.tf#L204) | Custom additive IAM settings for service identities in service => [role] format. | map(list(string)) | | {} | -| [services](variables.tf#L211) | Services to be enabled for the project. | list(string) | | [] | -| [vpc](variables.tf#L218) | VPC configuration for the project. | object({…}) | | null | +| [org_policies](variables.tf#L117) | Org-policy overrides at project level. | map(object({…})) | | {} | +| [service_accounts](variables.tf#L158) | Service accounts to be created, and roles assigned them on the project. | map(list(string)) | | {} | +| [service_accounts_additive](variables.tf#L164) | Service accounts to be created, and roles assigned them on the project additively. | map(list(string)) | | {} | +| [service_accounts_iam](variables.tf#L170) | IAM bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]}. | map(map(list(string))) | | {} | +| [service_accounts_iam_additive](variables.tf#L177) | IAM additive bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]}. | map(map(list(string))) | | {} | +| [service_identities_iam](variables.tf#L184) | Custom IAM settings for service identities in service => [role] format. | map(list(string)) | | {} | +| [service_identities_iam_additive](variables.tf#L191) | Custom additive IAM settings for service identities in service => [role] format. | map(list(string)) | | {} | +| [services](variables.tf#L198) | Services to be enabled for the project. | list(string) | | [] | +| [vpc](variables.tf#L205) | VPC configuration for the project. | object({…}) | | null | ## Outputs diff --git a/blueprints/factories/project-factory/main.tf b/blueprints/factories/project-factory/main.tf index 518d5a69c4..9dbe1721f5 100644 --- a/blueprints/factories/project-factory/main.tf +++ b/blueprints/factories/project-factory/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. diff --git a/blueprints/factories/project-factory/sample-data/projects/project.yaml b/blueprints/factories/project-factory/sample-data/projects/project.yaml index 0344991380..d8cf982ea2 100644 --- a/blueprints/factories/project-factory/sample-data/projects/project.yaml +++ b/blueprints/factories/project-factory/sample-data/projects/project.yaml @@ -44,19 +44,23 @@ kms_service_agents: # [opt] Labels for the project - merged with the ones defined in defaults labels: - environment: dev + environment: dev2 + costcenter: apps # [opt] Org policy overrides defined at project level org_policies: - constraints/compute.disableGuestAttributesAccess: - enforce: true - constraints/compute.trustedImageProjects: - allow: - values: + compute.disableGuestAttributesAccess: + rules: + - enforce: true + compute.trustedImageProjects: + rules: + - allow: + values: - projects/fast-dev-iac-core-0 - constraints/compute.vmExternalIpAccess: - deny: - all: true + compute.vmExternalIpAccess: + rules: + - deny: + all: true # [opt] Prefix - overrides default if set prefix: test1 @@ -67,7 +71,7 @@ service_accounts: another-service-account: - roles/compute.admin my-service-account: - - roles/compute.admin + - roles/compute.adminv1 # [opt] APIs to enable on the project. services: @@ -100,4 +104,4 @@ vpc: subnets_iam: europe-west1/dev-default-ew1: - user:foobar@example.com - - serviceAccount:service-account1 + - serviceAccount:my-service-account diff --git a/blueprints/factories/project-factory/variables.tf b/blueprints/factories/project-factory/variables.tf index 3aa3fa36b4..a2089bcfec 100644 --- a/blueprints/factories/project-factory/variables.tf +++ b/blueprints/factories/project-factory/variables.tf @@ -119,19 +119,6 @@ variable "org_policies" { type = map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) - - # default (unconditional) values - allow = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - deny = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - enforce = optional(bool, true) # for boolean policies only. - - # conditional values rules = optional(list(object({ allow = optional(object({ all = optional(bool) @@ -141,13 +128,13 @@ variable "org_policies" { all = optional(bool) values = optional(list(string)) })) - enforce = optional(bool, true) # for boolean policies only. - condition = object({ + enforce = optional(bool) # for boolean policies only. + condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) - }) + }), {}) })), []) })) default = {} diff --git a/blueprints/gke/binauthz/README.md b/blueprints/gke/binauthz/README.md index 387ceb09b7..09eac687d7 100644 --- a/blueprints/gke/binauthz/README.md +++ b/blueprints/gke/binauthz/README.md @@ -125,3 +125,18 @@ Once done testing, you can clean up resources by running `terraform destroy`. | [image_repo_url](outputs.tf#L22) | Image source repository url. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/gke/binauthz" + prefix = "test" + project_create = { + billing_account_id = "12345-12345-12345" + parent = "folders/123456789" + } + project_id = "my-project" +} +# tftest modules=14 resources=47 +``` diff --git a/blueprints/gke/multi-cluster-mesh-gke-fleet-api/README.md b/blueprints/gke/multi-cluster-mesh-gke-fleet-api/README.md index 7d43bd4011..f381327a2c 100644 --- a/blueprints/gke/multi-cluster-mesh-gke-fleet-api/README.md +++ b/blueprints/gke/multi-cluster-mesh-gke-fleet-api/README.md @@ -75,3 +75,34 @@ Once done testing, you can clean up resources by running `terraform destroy`. | [region](variables.tf#L99) | Region. | string | | "europe-west1" | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/gke/multi-cluster-mesh-gke-fleet-api" + billing_account_id = "123-456-789" + parent = "folders/123456789" + host_project_id = "my-host-project" + fleet_project_id = "my-fleet-project" + mgmt_project_id = "my-mgmt-project" + region = "europe-west1" + clusters_config = { + cluster-a = { + subnet_cidr_block = "10.0.1.0/24" + master_cidr_block = "10.16.0.0/28" + services_cidr_block = "192.168.1.0/24" + pods_cidr_block = "172.16.0.0/20" + } + cluster-b = { + subnet_cidr_block = "10.0.2.0/24" + master_cidr_block = "10.16.0.16/28" + services_cidr_block = "192.168.2.0/24" + pods_cidr_block = "172.16.16.0/20" + } + } + mgmt_subnet_cidr_block = "10.0.0.0/24" + istio_version = "1.14.1-asm.3" +} +# tftest modules=13 resources=57 +``` diff --git a/blueprints/gke/multitenant-fleet/main.tf b/blueprints/gke/multitenant-fleet/main.tf index 588d6c5b62..4079db99af 100644 --- a/blueprints/gke/multitenant-fleet/main.tf +++ b/blueprints/gke/multitenant-fleet/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -64,10 +64,10 @@ module "gke-project-0" { } # specify project-level org policies here if you need them # policy_boolean = { - # "constraints/compute.disableGuestAttributesAccess" = true + # "compute.disableGuestAttributesAccess" = true # } # policy_list = { - # "constraints/compute.trustedImageProjects" = { + # "compute.trustedImageProjects" = { # inherit_from_parent = null # suggested_value = null # status = true diff --git a/blueprints/networking/README.md b/blueprints/networking/README.md index ec510d5649..e7c0b1ae6b 100644 --- a/blueprints/networking/README.md +++ b/blueprints/networking/README.md @@ -82,3 +82,11 @@ The emulated on-premises environment can be used to test access to different ser It is meant to be used as a starting point for most Shared VPC configurations, and to be integrated to the above blueprints where Shared VPC is needed in more complex network topologies.
+ +### Exposing applications to the internet via GCLB and Private Service Connect + + This [blueprint](./psc-glb-and-armor/) shows how to configure an external Google Cloud Load Balancer, with a simple Cloud Armor rule to protect against DDOS attacks, to provide an external endpoint to an application provided by another team via Private Service Connect (PSC). + +It is meant to be used as a starting point for users that want to explore PSC to reduce some of the complexity in their network setup. + +
\ No newline at end of file diff --git a/blueprints/networking/__need_fixing/nginx-reverse-proxy-cluster/versions.tf b/blueprints/networking/__need_fixing/nginx-reverse-proxy-cluster/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/__need_fixing/nginx-reverse-proxy-cluster/versions.tf +++ b/blueprints/networking/__need_fixing/nginx-reverse-proxy-cluster/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/__need_fixing/onprem-google-access-dns/versions.tf b/blueprints/networking/__need_fixing/onprem-google-access-dns/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/__need_fixing/onprem-google-access-dns/versions.tf +++ b/blueprints/networking/__need_fixing/onprem-google-access-dns/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/decentralized-firewall/README.md b/blueprints/networking/decentralized-firewall/README.md index 64a3e41caa..334fd0f26a 100644 --- a/blueprints/networking/decentralized-firewall/README.md +++ b/blueprints/networking/decentralized-firewall/README.md @@ -2,22 +2,22 @@ This example shows how a decentralized firewall management can be organized using the [firewall factory](../../factories/net-vpc-firewall-yaml/README.md). -This approach is a good fit when Shared VPCs are used across multiple application/infrastructure teams. A central repository keeps environment/team -specific folders with firewall definitions in `yaml` format. +This approach is a good fit when Shared VPCs are used across multiple application/infrastructure teams. A central repository keeps environment/team +specific folders with firewall definitions in `yaml` format. -In the current blueprint multiple teams can define their [VPC Firewall Rules](https://cloud.google.com/vpc/docs/firewalls) -for [dev](./firewall/dev) and [prod](./firewall/prod) environments using team specific subfolders. Rules defined in the +In the current blueprint multiple teams can define their [VPC Firewall Rules](https://cloud.google.com/vpc/docs/firewalls) +for [dev](./firewall/dev) and [prod](./firewall/prod) environments using team specific subfolders. Rules defined in the [common](./firewall/common) folder are applied to both dev and prod environments. -> **_NOTE:_** Common rules are meant to be used for situations where [hierarchical rules](https://cloud.google.com/vpc/docs/firewall-policies) -do not map precisely to requirements (e.g. SA, etc.) +> **_NOTE:_** Common rules are meant to be used for situations where [hierarchical rules](https://cloud.google.com/vpc/docs/firewall-policies) +do not map precisely to requirements (e.g. SA, etc.) This is the high level diagram: ![High-level diagram](diagram.png "High-level diagram") -The rules can be validated either using an automated process or a manual process (or a combination of -the two). There is an blueprint of a YAML-based validator using [Yamale](https://github.com/23andMe/Yamale) +The rules can be validated either using an automated process or a manual process (or a combination of +the two). There is an blueprint of a YAML-based validator using [Yamale](https://github.com/23andMe/Yamale) in the [`validator/`](validator/) subdirectory, which can be integrated as part of a CI/CD pipeline. @@ -41,3 +41,15 @@ in the [`validator/`](validator/) subdirectory, which can be integrated as part | [vpc](outputs.tf#L41) | Shared VPCs. | | + +## Test +```hcl +module "test" { + source = "./fabric/blueprints/networking/decentralized-firewall" + billing_account_id = "ABCDE-12345-ABCDE" + prefix = "prefix" + root_node = "organizations/0123456789" +} + +# tftest modules=9 resources=50 +``` diff --git a/blueprints/networking/decentralized-firewall/versions.tf b/blueprints/networking/decentralized-firewall/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/decentralized-firewall/versions.tf +++ b/blueprints/networking/decentralized-firewall/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/filtering-proxy-psc/README.md b/blueprints/networking/filtering-proxy-psc/README.md index 61631af587..5efdca021e 100644 --- a/blueprints/networking/filtering-proxy-psc/README.md +++ b/blueprints/networking/filtering-proxy-psc/README.md @@ -26,3 +26,19 @@ To simplify the usage of the proxy, a Cloud DNS private zone is created in each | [region](variables.tf#L75) | Default region for resources. | string | | "europe-west1" | + +## Test + + +```hcl +module "test" { + source = "./fabric/blueprints/networking/filtering-proxy-psc" + prefix = "fabric" + project_create = { + billing_account = "123456-ABCDEF-123456" + parent = "folders/1234567890" + } + project_id = "test-project" +} +# tftest modules=13 resources=37 +``` diff --git a/blueprints/networking/filtering-proxy-psc/versions.tf b/blueprints/networking/filtering-proxy-psc/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/filtering-proxy-psc/versions.tf +++ b/blueprints/networking/filtering-proxy-psc/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/filtering-proxy/README.md b/blueprints/networking/filtering-proxy/README.md index 9d7e2c0255..1e9df315de 100644 --- a/blueprints/networking/filtering-proxy/README.md +++ b/blueprints/networking/filtering-proxy/README.md @@ -36,3 +36,27 @@ You can optionally deploy the Squid server as [Managed Instance Group](https://c | [squid-address](outputs.tf#L17) | IP address of the Squid proxy. | | + +## Test + +```hcl +module "test1" { + source = "./fabric/blueprints/networking/filtering-proxy" + billing_account = "123456-123456-123456" + mig = true + prefix = "fabric" + root_node = "folders/123456789" +} +# tftest modules=14 resources=36 +``` + +```hcl +module "test2" { + source = "./fabric/blueprints/networking/filtering-proxy" + billing_account = "123456-123456-123456" + mig = false + prefix = "fabric" + root_node = "folders/123456789" +} +# tftest modules=12 resources=30 +``` diff --git a/blueprints/networking/filtering-proxy/main.tf b/blueprints/networking/filtering-proxy/main.tf index 06efa81475..b36f0140b5 100644 --- a/blueprints/networking/filtering-proxy/main.tf +++ b/blueprints/networking/filtering-proxy/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -227,8 +227,8 @@ module "folder-apps" { name = "apps" org_policies = { # prevent VMs with public IPs in the apps folder - "constraints/compute.vmExternalIpAccess" = { - deny = { all = true } + "compute.vmExternalIpAccess" = { + rules = [{ deny = { all = true } }] } } } diff --git a/blueprints/networking/filtering-proxy/versions.tf b/blueprints/networking/filtering-proxy/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/filtering-proxy/versions.tf +++ b/blueprints/networking/filtering-proxy/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/glb-and-armor/README.md b/blueprints/networking/glb-and-armor/README.md index 8385beab1e..25b9e96ffc 100644 --- a/blueprints/networking/glb-and-armor/README.md +++ b/blueprints/networking/glb-and-armor/README.md @@ -137,3 +137,19 @@ The above command will delete the associated resources so there will be no billa | [vm_siege_external_ip](outputs.tf#L23) | Siege VM external IP address. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/networking/glb-and-armor" + prefix = "test" + project_create = { + billing_account_id = "123456789" + parent = "organizations/123456789" + } + project_id = "project-1" + enforce_security_policy = true +} +# tftest modules=12 resources=26 +``` diff --git a/blueprints/networking/hub-and-spoke-peering/README.md b/blueprints/networking/hub-and-spoke-peering/README.md index d39cb3aa21..e9a05cf257 100644 --- a/blueprints/networking/hub-and-spoke-peering/README.md +++ b/blueprints/networking/hub-and-spoke-peering/README.md @@ -100,3 +100,20 @@ The VPN used to connect the GKE masters VPC does not account for HA, upgrading t | [vms](outputs.tf#L20) | GCE VMs. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/networking/hub-and-spoke-peering" + prefix = "prefix" + project_create = { + billing_account = "123456-123456-123456" + oslogin = true + parent = "folders/123456789" + } + project_id = "project-1" +} + +# tftest modules=22 resources=61 +``` diff --git a/blueprints/networking/hub-and-spoke-peering/versions.tf b/blueprints/networking/hub-and-spoke-peering/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/hub-and-spoke-peering/versions.tf +++ b/blueprints/networking/hub-and-spoke-peering/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/hub-and-spoke-vpn/README.md b/blueprints/networking/hub-and-spoke-vpn/README.md index bdf877c737..9cfca228f1 100644 --- a/blueprints/networking/hub-and-spoke-vpn/README.md +++ b/blueprints/networking/hub-and-spoke-vpn/README.md @@ -101,3 +101,18 @@ ping test-r2.dev.example.com | [vms](outputs.tf#L39) | GCE VMs. | | + +## Test +```hcl +module "test" { + source = "./fabric/blueprints/networking/hub-and-spoke-vpn" + prefix = "prefix" + project_create_config = { + billing_account_id = "123456-123456-123456" + parent_id = "folders/123456789" + } + project_id = "project-1" +} + +# tftest modules=20 resources=73 +``` diff --git a/blueprints/networking/hub-and-spoke-vpn/versions.tf b/blueprints/networking/hub-and-spoke-vpn/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/hub-and-spoke-vpn/versions.tf +++ b/blueprints/networking/hub-and-spoke-vpn/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf b/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf index 4d1236bb8b..49ced39478 100644 --- a/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf +++ b/blueprints/networking/hub-and-spoke-vpn/vpn-dev-r1.tf @@ -27,7 +27,9 @@ module "landing-to-dev-vpn-r1" { name = "${var.prefix}-lnd-vpn-r1" asn = 64514 } - peer_gateway = { gcp = module.dev-to-landing-vpn-r1.self_link } + peer_gateways = { + default = { gcp = module.dev-to-landing-vpn-r1.self_link } + } tunnels = { 0 = { bgp_peer = { @@ -63,7 +65,9 @@ module "dev-to-landing-vpn-r1" { mode = "CUSTOM" } } - peer_gateway = { gcp = module.landing-to-dev-vpn-r1.self_link } + peer_gateways = { + default = { gcp = module.landing-to-dev-vpn-r1.self_link } + } tunnels = { 0 = { bgp_peer = { diff --git a/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf b/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf index 8e633686fa..8c025d9ee9 100644 --- a/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf +++ b/blueprints/networking/hub-and-spoke-vpn/vpn-prod-r1.tf @@ -28,7 +28,9 @@ module "landing-to-prod-vpn-r1" { ip_ranges = coalesce(var.vpn_configs.land-r1.custom_ranges, {}) } } - peer_gateway = { gcp = module.prod-to-landing-vpn-r1.self_link } + peer_gateways = { + default = { gcp = module.prod-to-landing-vpn-r1.self_link } + } tunnels = { 0 = { bgp_peer = { @@ -64,7 +66,9 @@ module "prod-to-landing-vpn-r1" { ip_ranges = coalesce(var.vpn_configs.prod-r1.custom_ranges, {}) } } - peer_gateway = { gcp = module.landing-to-prod-vpn-r1.self_link } + peer_gateways = { + default = { gcp = module.landing-to-prod-vpn-r1.self_link } + } tunnels = { 0 = { bgp_peer = { diff --git a/blueprints/networking/ilb-next-hop/README.md b/blueprints/networking/ilb-next-hop/README.md index c3091558ca..b4b5e6e866 100644 --- a/blueprints/networking/ilb-next-hop/README.md +++ b/blueprints/networking/ilb-next-hop/README.md @@ -86,3 +86,15 @@ A sample testing session using `tmux`: | [ssh_vm_right](outputs.tf#L64) | Command-line login to right VMs. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/networking/ilb-next-hop" + prefix = "test" + project_create = true + project_id = "project-1" +} +# tftest modules=18 resources=42 +``` diff --git a/blueprints/networking/ilb-next-hop/versions.tf b/blueprints/networking/ilb-next-hop/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/ilb-next-hop/versions.tf +++ b/blueprints/networking/ilb-next-hop/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/private-cloud-function-from-onprem/README.md b/blueprints/networking/private-cloud-function-from-onprem/README.md index d0d7ffdb4d..111e82a4f7 100644 --- a/blueprints/networking/private-cloud-function-from-onprem/README.md +++ b/blueprints/networking/private-cloud-function-from-onprem/README.md @@ -33,3 +33,17 @@ curl https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/YOUR_FUNCTION_NAME | [function_url](outputs.tf#L17) | URL of the Cloud Function. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/networking/private-cloud-function-from-onprem/" + project_create = { + billing_account_id = "123456-ABCDEF-123456" + parent = "folders/1234567890" + } + project_id = "test-project" +} +# tftest modules=11 resources=40 +``` diff --git a/blueprints/networking/private-cloud-function-from-onprem/main.tf b/blueprints/networking/private-cloud-function-from-onprem/main.tf index 1848e95314..49bab2527a 100644 --- a/blueprints/networking/private-cloud-function-from-onprem/main.tf +++ b/blueprints/networking/private-cloud-function-from-onprem/main.tf @@ -86,7 +86,9 @@ module "vpn-onprem" { ip_ranges = {} } } - peer_gateway = { gcp = module.vpn-hub.self_link } + peer_gateways = { + default = { gcp = module.vpn-hub.self_link } + } tunnels = { tunnel-0 = { bgp_peer = { @@ -122,7 +124,9 @@ module "vpn-hub" { } } } - peer_gateway = { gcp = module.vpn-onprem.self_link } + peer_gateways = { + default = { gcp = module.vpn-onprem.self_link } + } tunnels = { tunnel-0 = { diff --git a/blueprints/networking/private-cloud-function-from-onprem/versions.tf b/blueprints/networking/private-cloud-function-from-onprem/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/private-cloud-function-from-onprem/versions.tf +++ b/blueprints/networking/private-cloud-function-from-onprem/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/networking/psc-glb-and-armor/README.md b/blueprints/networking/psc-glb-and-armor/README.md new file mode 100644 index 0000000000..c9e101e8b7 --- /dev/null +++ b/blueprints/networking/psc-glb-and-armor/README.md @@ -0,0 +1,127 @@ +# HTTP Load Balancer with Cloud Armor and Private Service Connect + +## Introduction + +This blueprint contains all necessary Terraform code to configure HTTP load balancing and Google’s advanced WAF security tool (Cloud Armor) on top to securely deploy an application, provided by another team. + +This tutorial is general enough to fit in a variety of use-cases, from hosting a mobile app's backend to deploy proprietary workloads at scale. + +## Architecture + +

+ +The main components that we would be setting up are (to learn more about these products, click on the hyperlinks): + +* [Cloud Armor](https://cloud.google.com/armor) - Google Cloud Armor is the web-application firewall (WAF) and DDoS mitigation service that helps users defend their web apps and services at Google scale at the edge of Google’s network. +* [Cloud Load Balancer](https://cloud.google.com/load-balancing) - When your app usage spikes, it is important to scale, optimize and secure the app. Cloud Load Balancing is a fully distributed solution that balances user traffic to multiple backends to avoid congestion, reduce latency and increase security. Some important features it offers that we use here are: + * Single global anycast IP and autoscaling - CLB acts as a frontend to all your backend instances across all regions. It provides cross-region load balancing, automatic multi-region failover and scales to support increase in resources. + * Global Forwarding Rule - To route traffic to different regions, global load balancers use global forwarding rules, which bind the global IP address and a single target proxy. + * Target Proxy - For external HTTP(S) load balancers, proxies route incoming requests to a URL map. This is essentially how you can handle the connections. + * URL Map - URL Maps are used to route requests to a backend service based on the rules that you define for the host and path of an incoming URL. + * Backend Service - A Backend Service defines CLB distributes traffic. The backend service configuration consists of a set of values - protocols to connect to backends, session settings, health checks and timeouts. + * Health Check - Health check is a method provided to determine if the corresponding backends respond to traffic. Health checks connect to backends on a configurable, periodic basis. Each connection attempt is called a probe. Google Cloud records the success or failure of each probe. +* [Private Service Connect](https://cloud.google.com/vpc/docs/private-service-connect) - Private Service Connect. Private Service Connect allows private consumption of services across VPC networks that belong to different groups, teams, projects, or organizations. You can publish and consume services using IP addresses that you define and that are internal to your VPC network. No VPC peering or VPN is needed between the consumer and produce of the service. +* [Cloud Run](https://cloud.google.com/run) - Cloud Run is a fully managed container runtime on Google Cloud. In this blueprint it's used to host [httpbin](http://httpbin.org/), which is a simple HTTP server application. The setup the blueprint showcases will also work with GCE or GKE, but might need small adjustments. + +This architecture is ideal, if the external Load Balancer and the application are managed by different teams. The application team configures the application using the Internal Load Balancer, they have all the freedom how they evolve and change their implementation. The load balancer team, configures the load balancer and assures security using Cloud Armor. + +In a real world implementation, the IaC code might be split into two separate repositories, and the application team raises changes to the load balancer using a pull request. Also the service attachment in the producer project is configured to allow all connections via `connection_preference = "ACCEPT_AUTOMATIC"` in a real world setup you would want to use a manual white listing instead. + +The Terraform IaC also deploys a VM to the producer VPC network, this VM is only needed for the internal Layer 7 Load Balancer to properly work with Cloud Run, but has no logical function in the setup, no traffic is routed via this machine. + +## Setup + +This solution assumes you already have two projects created and set up where you wish to host these resources. If not, and you would like for the projects to create a new project as well, please refer to the [github repository](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/master/blueprints/data-solutions/gcs-to-bq-with-least-privileges) for instructions. + +### Prerequisites + +* Have an [organization](https://cloud.google.com/resource-manager/docs/creating-managing-organization) set up in Google cloud. +* Have a [billing account](https://cloud.google.com/billing/docs/how-to/manage-billing-account) set up. +* Have two existing [projects](https://cloud.google.com/resource-manager/docs/creating-managing-projects) with [billing enabled](https://cloud.google.com/billing/docs/how-to/modify-project). + +### Roles & Permissions + +In order to spin up this architecture, you will need to be a user with the “__Project owner__” [IAM](https://cloud.google.com/iam) role on the existing project: + +Note: To grant a user a role, take a look at the [Granting and Revoking Access](https://cloud.google.com/iam/docs/granting-changing-revoking-access#grant-single-role) documentation. + +### Spinning up the architecture + +#### Step 1: Cloning the repository + +Click on the button below, sign in if required and when the prompt appears, click on “confirm”. + +[![Open Cloudshell](../../../assets/images/cloud-shell-button.png)](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=blueprints%2Fnetworking%2Fpsc-glb-and-armor) + +This will clone the repository to your cloud shell and a screen like this one will appear: + +![cloud_shell](../glb-and-armor/cloud_shell.png) + +Before we deploy the architecture, you will need the following information: + +* The __project IDs__. + +#### Step 2: Deploying the resources + +1. After cloning the repo, and going through the prerequisites, head back to the cloud shell editor. +2. Make sure you’re in the following directory. if not, you can change your directory to it via the ‘cd’ command: + + cloudshell_open/cloud-foundation-fabric/blueprints/cloud-operations/glb_and_armor + +3. Run the following command to initialize the terraform working directory: + + terraform init + +4. Copy the following command into a console and replace __[consumer-project-id]__ and __[produce-project-id]__ with your project’s IDs. Then run the following command to run the terraform script and create all relevant resources for this architecture: + + terraform apply -var consumer_project_id=[consumer-project-id] -var producer_project_id=[producer-project-id] + +The resource creation will take a few minutes… but when it’s complete, you should see an output stating the command completed successfully with a list of the created resources. + +__Congratulations__! You have successfully deployed an HTTP Load Balancer with Cloud Armor security and a PSC based backend server. + +## Testing your architecture + +You can simply invoke the service by calling + + curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" -H "Content-Type: application/json" http://$LB_IP + +## Cleaning up your environment + +The easiest way to remove all the deployed resources is to run the following command in Cloud Shell: + + terraform destroy + +The above command will delete the associated resources so there will be no billable charges made afterwards. + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [consumer_project_id](variables.tf#L17) | The consumer project, in which the GCLB and Cloud Armor should be created. | string | ✓ | | +| [prefix](variables.tf#L22) | Prefix used for resource names. | string | ✓ | | +| [producer_project_id](variables.tf#L31) | The producer project, in which the ILB, PSC Service Attachment and Cloud Run service should be created. | string | ✓ | | +| [project_create](variables.tf#L36) | Create project instead of using an existing one. | bool | | false | +| [region](variables.tf#L42) | The GCP region in which the resources should be deployed. | string | | "europe-west1" | +| [zone](variables.tf#L48) | The GCP zone for the VM. | string | | "europe-west1-b" | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [lb_ip](outputs.tf#L17) | Load balancer IP address. | | + + +## Test + +```hcl +module "psc-glb-and-armor-test" { + source = "./fabric/blueprints/networking/psc-glb-and-armor" + prefix = "test" + project_create = true + consumer_project_id = "project-1" + producer_project_id = "project-2" +} +# tftest modules=3 resources=31 +``` diff --git a/blueprints/networking/psc-glb-and-armor/consumer.tf b/blueprints/networking/psc-glb-and-armor/consumer.tf new file mode 100644 index 0000000000..4e02c9e0f9 --- /dev/null +++ b/blueprints/networking/psc-glb-and-armor/consumer.tf @@ -0,0 +1,98 @@ +/** + * 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. + */ + +module "consumer_project" { + source = "../../../modules/project" + name = var.consumer_project_id + project_create = var.project_create + services = [ + "iam.googleapis.com", + "compute.googleapis.com", + ] +} + +resource "google_compute_region_network_endpoint_group" "psc_neg" { + name = "psc-neg" + region = var.region + project = module.consumer_project.project_id + network_endpoint_type = "PRIVATE_SERVICE_CONNECT" + psc_target_service = google_compute_service_attachment.psc_ilb_service_attachment.self_link + + network = "default" + subnetwork = "default" +} + +resource "google_compute_global_forwarding_rule" "default" { + project = module.consumer_project.project_id + name = "global-rule" + load_balancing_scheme = "EXTERNAL_MANAGED" + target = google_compute_target_http_proxy.default.id + port_range = "80" +} + +resource "google_compute_target_http_proxy" "default" { + project = module.consumer_project.project_id + name = "target-proxy" + description = "a description" + url_map = google_compute_url_map.default.id +} + +resource "google_compute_url_map" "default" { + project = module.consumer_project.project_id + name = "url-map-target-proxy" + description = "A simple URL Map, routing all traffic to the PSC NEG" + default_service = google_compute_backend_service.default.id + + host_rule { + hosts = ["*"] + path_matcher = "allpaths" + } + + path_matcher { + name = "allpaths" + default_service = google_compute_backend_service.default.id + + path_rule { + paths = ["/*"] + service = google_compute_backend_service.default.id + } + } +} + +resource "google_compute_security_policy" "policy" { + provider = google-beta + project = module.consumer_project.project_id + name = "ddos-protection" + adaptive_protection_config { + layer_7_ddos_defense_config { + enable = true + } + } +} + +resource "google_compute_backend_service" "default" { + provider = google-beta + project = module.consumer_project.project_id + name = "backend" + load_balancing_scheme = "EXTERNAL_MANAGED" + protocol = "HTTPS" + security_policy = google_compute_security_policy.policy.id + backend { + group = google_compute_region_network_endpoint_group.psc_neg.id + balancing_mode = "UTILIZATION" + capacity_scaler = 1.0 + } +} \ No newline at end of file diff --git a/blueprints/networking/psc-glb-and-armor/diagram.png b/blueprints/networking/psc-glb-and-armor/diagram.png new file mode 100644 index 0000000000..d72625a579 Binary files /dev/null and b/blueprints/networking/psc-glb-and-armor/diagram.png differ diff --git a/tests/blueprints/factories/cloud_identity_group_factory/fixture/main.tf b/blueprints/networking/psc-glb-and-armor/outputs.tf similarity index 75% rename from tests/blueprints/factories/cloud_identity_group_factory/fixture/main.tf rename to blueprints/networking/psc-glb-and-armor/outputs.tf index 4f56c63c22..b8e50ed43c 100644 --- a/tests/blueprints/factories/cloud_identity_group_factory/fixture/main.tf +++ b/blueprints/networking/psc-glb-and-armor/outputs.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -14,8 +14,7 @@ * limitations under the License. */ -module "test" { - source = "../../../../../blueprints/factories/cloud-identity-group-factory/" - customer_id = "customers/C01234567" - data_dir = "data" +output "lb_ip" { + description = "Load balancer IP address." + value = google_compute_global_forwarding_rule.default.ip_address } diff --git a/blueprints/networking/psc-glb-and-armor/producer.tf b/blueprints/networking/psc-glb-and-armor/producer.tf new file mode 100644 index 0000000000..5755aff1a9 --- /dev/null +++ b/blueprints/networking/psc-glb-and-armor/producer.tf @@ -0,0 +1,231 @@ +/** + * 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. + */ + +module "producer_project" { + source = "../../../modules/project" + name = var.producer_project_id + project_create = var.project_create + services = [ + "iam.googleapis.com", + "run.googleapis.com", + "compute.googleapis.com", + ] +} + +resource "google_service_account" "app" { + project = module.producer_project.project_id + account_id = "example-app" + display_name = "Example App Service Account" +} + +resource "google_cloud_run_service" "app" { + name = "example-app" + location = var.region + project = module.producer_project.project_id + + template { + spec { + containers { + image = "kennethreitz/httpbin:latest" + ports { + container_port = 80 + } + } + service_account_name = google_service_account.app.email + } + } + + autogenerate_revision_name = true + traffic { + percent = 100 + latest_revision = true + } + metadata { + annotations = { + "run.googleapis.com/ingress" = "internal-and-cloud-load-balancing" + } + } +} + +resource "google_compute_region_network_endpoint_group" "neg" { + name = "example-app-neg" + network_endpoint_type = "SERVERLESS" + region = var.region + project = module.producer_project.project_id + cloud_run { + service = google_cloud_run_service.app.name + } +} + +resource "google_compute_forwarding_rule" "psc_ilb_target_service" { + name = "producer-forwarding-rule" + region = var.region + project = module.producer_project.project_id + + load_balancing_scheme = "INTERNAL_MANAGED" + port_range = "443" + allow_global_access = true + target = google_compute_region_target_https_proxy.default.id + + network = google_compute_network.psc_ilb_network.name + subnetwork = google_compute_subnetwork.ilb_subnetwork.name +} + +resource "google_compute_region_target_https_proxy" "default" { + name = "l7-ilb-target-http-proxy" + provider = google-beta + region = var.region + project = module.producer_project.project_id + url_map = google_compute_region_url_map.default.id + ssl_certificates = [google_compute_region_ssl_certificate.default.id] +} + +resource "google_compute_region_ssl_certificate" "default" { + region = var.region + project = module.producer_project.project_id + name = "my-certificate" + private_key = tls_private_key.example.private_key_pem + certificate = tls_self_signed_cert.example.cert_pem +} + +resource "google_compute_region_url_map" "default" { + name = "l7-ilb-regional-url-map" + provider = google-beta + region = var.region + project = module.producer_project.project_id + default_service = google_compute_region_backend_service.producer_service_backend.id +} + +resource "tls_private_key" "example" { + algorithm = "RSA" + rsa_bits = 2048 +} + +resource "tls_self_signed_cert" "example" { + private_key_pem = tls_private_key.example.private_key_pem + + subject { + common_name = "app.example.com" + organization = "Org" + } + + validity_period_hours = 12 + + allowed_uses = [ + "key_encipherment", + "digital_signature", + "server_auth", + ] +} +resource "google_compute_region_backend_service" "producer_service_backend" { + name = "producer-service" + region = var.region + project = module.producer_project.project_id + load_balancing_scheme = "INTERNAL_MANAGED" + protocol = "HTTPS" + + backend { + group = google_compute_region_network_endpoint_group.neg.id + balancing_mode = "UTILIZATION" + capacity_scaler = 1.0 + } +} + +resource "google_compute_network" "psc_ilb_network" { + name = "psc-ilb-network" + auto_create_subnetworks = false + project = module.producer_project.project_id +} + +resource "google_compute_subnetwork" "ilb_subnetwork" { + name = "ilb-subnetwork" + region = var.region + project = module.producer_project.project_id + + network = google_compute_network.psc_ilb_network.id + ip_cidr_range = "10.0.0.0/16" + purpose = "INTERNAL_HTTPS_LOAD_BALANCER" + role = "ACTIVE" +} + +resource "google_compute_subnetwork" "psc_private_subnetwork" { + name = "psc-private-subnetwork" + region = var.region + project = module.producer_project.project_id + + network = google_compute_network.psc_ilb_network.id + ip_cidr_range = "10.3.0.0/16" + purpose = "PRIVATE" + role = "ACTIVE" +} + +resource "google_compute_subnetwork" "psc_ilb_nat" { + name = "psc-ilb-nat" + region = var.region + project = module.producer_project.project_id + + network = google_compute_network.psc_ilb_network.id + purpose = "PRIVATE_SERVICE_CONNECT" + ip_cidr_range = "10.1.0.0/16" +} + +resource "google_compute_subnetwork" "vms" { + name = "vms" + region = var.region + project = module.producer_project.project_id + + network = google_compute_network.psc_ilb_network.id + ip_cidr_range = "10.4.0.0/16" +} + +resource "google_compute_service_attachment" "psc_ilb_service_attachment" { + name = "my-psc-ilb" + region = var.region + project = module.producer_project.project_id + description = "A service attachment configured with Terraform" + + enable_proxy_protocol = false + connection_preference = "ACCEPT_AUTOMATIC" + nat_subnets = [google_compute_subnetwork.psc_ilb_nat.id] + target_service = google_compute_forwarding_rule.psc_ilb_target_service.id +} + +resource "google_service_account" "noop" { + project = module.producer_project.project_id + account_id = "noop-sa" + display_name = "Service Account for NOOP VM" +} + +resource "google_compute_instance" "noop-vm" { + project = module.producer_project.project_id + name = "noop-ilb-vm" + machine_type = "e2-medium" + zone = var.zone + boot_disk { + initialize_params { + image = "debian-cloud/debian-11" + } + } + + network_interface { + network = google_compute_network.psc_ilb_network.id + subnetwork = google_compute_subnetwork.vms.id + } + service_account { + email = google_service_account.noop.email + scopes = [] + } +} \ No newline at end of file diff --git a/blueprints/networking/psc-glb-and-armor/variables.tf b/blueprints/networking/psc-glb-and-armor/variables.tf new file mode 100644 index 0000000000..b8715ea697 --- /dev/null +++ b/blueprints/networking/psc-glb-and-armor/variables.tf @@ -0,0 +1,52 @@ +/** + * 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. + */ + +variable "consumer_project_id" { + description = "The consumer project, in which the GCLB and Cloud Armor should be created." + type = string +} + +variable "prefix" { + description = "Prefix used for resource names." + type = string + validation { + condition = var.prefix != "" + error_message = "Prefix cannot be empty." + } +} + +variable "producer_project_id" { + description = "The producer project, in which the ILB, PSC Service Attachment and Cloud Run service should be created." + type = string +} + +variable "project_create" { + description = "Create project instead of using an existing one." + type = bool + default = false +} + +variable "region" { + description = "The GCP region in which the resources should be deployed." + type = string + default = "europe-west1" +} + +variable "zone" { + description = "The GCP zone for the VM." + type = string + default = "europe-west1-b" +} \ No newline at end of file diff --git a/blueprints/networking/shared-vpc-gke/README.md b/blueprints/networking/shared-vpc-gke/README.md index 858518bd89..f413becfdd 100644 --- a/blueprints/networking/shared-vpc-gke/README.md +++ b/blueprints/networking/shared-vpc-gke/README.md @@ -70,3 +70,15 @@ There's a minor glitch that can surface running `terraform destroy`, where the s | [vpc](outputs.tf#L40) | Shared VPC. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/gke/shared-vpc-gke" + billing_account_id = "ABCDE-12345-ABCDE" + prefix = "test" + root_node = "organizations/0123456789" +} +# tftest modules=11 resources=43 +``` diff --git a/blueprints/networking/shared-vpc-gke/versions.tf b/blueprints/networking/shared-vpc-gke/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/networking/shared-vpc-gke/versions.tf +++ b/blueprints/networking/shared-vpc-gke/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/blueprints/serverless/README.md b/blueprints/serverless/README.md index 44f39f0f66..03d2a8aec2 100644 --- a/blueprints/serverless/README.md +++ b/blueprints/serverless/README.md @@ -10,3 +10,8 @@ They are meant to be used as minimal but complete starting points to create actu This [blueprint](./api-gateway/) shows how to configure a load balancer to enable multi-region deployments for API Gateway. For more details on how this set up work have a look at the article [here](https://cloud.google.com/api-gateway/docs/multi-region-deployment)
+ +### Cloud Run series + + These are a series of blueprints developing the chapters of the __Serverless Networking Guide__ (to be released soon), focused in Cloud Run. +
diff --git a/blueprints/serverless/api-gateway/README.md b/blueprints/serverless/api-gateway/README.md index 9e17b11e92..42ae2460c0 100644 --- a/blueprints/serverless/api-gateway/README.md +++ b/blueprints/serverless/api-gateway/README.md @@ -22,6 +22,8 @@ Clone this repository or [open it in cloud shell](https://ssh.cloud.google.com/c curl -v http:///hello Once done testing, you can clean up resources by running `terraform destroy`. + + ## Variables @@ -39,3 +41,21 @@ Once done testing, you can clean up resources by running `terraform destroy`. | [ip_address](outputs.tf#L17) | The reserved global IP address. | | + +## Test + +```hcl +module "test" { + source = "./fabric/blueprints/serverless/api-gateway" + project_create = { + billing_account_id = "123456789" + parent = "organizations/123456789" + } + project_id = "project-1" + regions = [ + "europe-west1", + "europe-west2" + ] +} +# tftest modules=8 resources=34 +``` diff --git a/blueprints/serverless/cloud-run-corporate/README.md b/blueprints/serverless/cloud-run-corporate/README.md new file mode 100644 index 0000000000..fc766b0204 --- /dev/null +++ b/blueprints/serverless/cloud-run-corporate/README.md @@ -0,0 +1,287 @@ +# Cloud Run Corporate + +## Introduction + +This blueprint contains all the necessary Terraform modules to build and __privately__ expose a Cloud Run service in a variety of use cases. + +The content of this blueprint corresponds to the chapter '_Developing an enterprise application - The corporate environment_' of the __Serverless Networking Guide__ (to be released soon). This guide is an easy to follow introduction to Cloud Run, where a couple of friendly characters will guide you from the basics to more advanced topics with a very practical approach and in record time! The code here complements this learning and allows you to test the scenarios presented and your knowledge. + +If you are interested in following this guide, take a look to the chapters' blueprints: +* [My serverless "Hello, World! - Exploring Cloud Run](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/master/blueprints/serverless/cloud-run-explore) +* [Developing an enterprise application - The corporate environment](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/master/blueprints/serverless/cloud-run-corporate) + +## Architecture + +This blueprint creates multiple architectures depending on the use case. Some may have one or two projecs while others may have three or more. Some use [Private Service Connect (PSC)](https://cloud.google.com/vpc/docs/private-service-connect) to access Google APIs, and others a [Layer 7 Internal Load Balancer](https://cloud.google.com/load-balancing/docs/l7-internal). Even security plays a role and [VPC Service Controls (VPC SC)](https://cloud.google.com/vpc-service-controls) is introduced. + +## Prerequisites + +Depending on the use case, you will need one or more projects with [billing enabled](https://cloud.google.com/billing/docs/how-to/modify-project) and a user with the “Project owner” [IAM](https://cloud.google.com/iam) role on those projects. You can use existing projects or let the blueprint creates them for you but in that case you will need to add extra information for each project. E.g.: + +```tfvars +# Create the main project +prj_main_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" +} +``` + +Below it is explained how to set this information. + +## Spinning up the architecture + +### General steps + +1. Clone the repo to your local machine or Cloud Shell: +```bash +git clone https://github.com/GoogleCloudPlatform/cloud-foundation-fabric +``` + +2. Change to the directory of the blueprint: +```bash +cd cloud-foundation-fabric/blueprints/serverless/cloud-run-corporate +``` +You should see this README and some terraform files. + +3. To deploy a specific use case, you will need to create a file in this directory called `terraform.tfvars` and follow the corresponding instructions to set variables. Sometimes values that are meant to be substituted will be shown inside brackets but you need to omit these brackets. E.g.: +```tfvars +project_id = "[your-project_id]" +``` +may become +```tfvars +project_id = "spiritual-hour-331417" +``` + +Use cases are self-contained so you can deploy any of them at will. + +4. The usual terraform commands will do the work: +```bash +terraform init +terraform plan +terraform apply +``` + +The resource creation will take a few minutes but when it’s complete, you should see an output stating the command completed successfully with a list of the created resources, and some output variables with information to access your service. + +__Congratulations!__ You have successfully deployed the use case you chose based on the variables configuration. + +### Use case 1: Access to Cloud Run from a VM in the project + +This use case deploys a Cloud Run service and a VM in the same project. To privately access Cloud Run from the VM, PSC is used. A PSC endpoint is created so that the VM can reach the service through an RFC1918 IP. Also, a DNS entry is created to point the service's default URL to that IP. + +

+ +In this case the only variable that you need to set in `terraform.tfvars` is the main project ID: +```tfvars +prj_main_id = "[your-main-project-id]" +``` +Alternatively you can pass this value on the command line: +```bash +terraform apply -var prj_main_id="[your-main-project-id]" +``` + +The default URL is automatically created and shown as a terraform output variable. It will be similar to the one shown in the picture above. Now SSH into the VM and run `curl`, you should see the following: + +

+ +Note that the VM is resolving the Cloud Run service to an internal IP, 10.0.0.100. Public access is restricted, if you try to `curl` from e.g. your laptop you will get a `403 Forbidden` error. + +### Use case 2: Access to Cloud Run from on-prem environment + +This use case deploys a Cloud Run service in a GCP project and simulates an on-prem environment with another GCP project and a HA VPN connection between them. PSC is still used but now the DNS configuration should happen in on-premises. Since this environment is implemented in GCP, the blueprint takes care of this configuration. The PSC endpoint is announced through the VPN via BGP so that on-prem knows how to reach it. A VM is deployed in the on-prem environment to test this setup. + +

+ +You will need to set both the main and the on-prem project IDs in `terraform.tfvars`: +```tfvars +prj_main_id = "[your-main-project-id]" +prj_onprem_id = "[your-onprem-project-id]" +``` + +SSH into the test VM and run `curl`, you should see the same output as in the previous use case. + +### Use case 3: Access to Cloud Run from another project + +Corporate apps are used by multiple teams and projects. This blueprint explores accessing from a different project to where Cloud Run is deployed. For simplicity only one more project is used but the concepts would apply to any number of projects. Three different cases are implemented: + +#### Use case 3.1 + +The first case allows access to Cloud Run from any project as well as the Internet. + +

+ +This is achieved with `ingress_settings` value set to `"all"`. This is the default if not specified but this blueprint sets it to `"internal"` instead. Add a new project and this setting in `terraform.tfvars`: + +```tfvars +prj_main_id = "[your-main-project-id]" +prj_prj1_id = "[your-project1-id]" +ingress_settings = "all" +``` + +Note the different PSC endpoints created in each project and the different IPs. Each project can choose its own RFC1918 IP to reach the same Cloud Run service. + +#### Use case 3.2 + +It is possible to block access from the Internet restoring `ingress_settigns` to `"internal"` but this will also block access from any other project. This feature is interesting, as will be shown in the next use case. + +

+ +Simply omit `ingress_settigns` in `terraform.tfvars`: + +```tfvars +prj_main_id = "[your-main-project-id]" +prj_prj1_id = "[your-project1-id]" +``` + +#### Use case 3.3 + +To allow access from other projects while keeping access from the Internet restricted, you need to add those projects to a VPC SC perimeter together with Cloud Run. Projects outisde the perimeter will be blocked. This way you can control which projects can gain access. + +

+ +VPC SC requires an [Access Policy](https://cloud.google.com/access-context-manager/docs/overview#access-policies). You can use an existing policy or create a new one, but an organization can only have one organization-level access policy. The policy name is a unique numeric identifier assigned by Google Cloud. + +Make sure to check out the [IAM roles](https://cloud.google.com/access-context-manager/docs/access-control) required to configure access policies and VPC SC. Also, include the identity that runs Terraform to avoid losing access from it once the perimeter is created. Set the following in `terraform.tfvars`: + +```tfvars +prj_main_id = "[your-main-project-id]" +prj_prj1_id = "[your-project1-id]" +access_policy = "[policy-name]" +tf_identity = "[user or SA account]" +``` + +#### Use case 3.4 + +Another possibility is for a project to be a Service Project with the Cloud Run service running in the Host Project, since this is also considered `"internal"` traffic. In this case a VPC SC perimeter is not needed. + +

+ +Note that the service project can't have a different DNS entry for the same domain, so it uses the DNS and PSC configuration of the host project. Set the following in `terraform.tfvars`: + +```tfvars +prj_main_id = "[your-main-project-id]" # Used as host project +prj_svc1_id = "[your-service-project1-id]" +``` + +### Use case 4: Access to Cloud Run with custom domain + +You need to use a L7 ILB with Serverless NEGs (in Preview) to set a custom domain for Cloud Run. As a practical example, this blueprint deploys this configuration in a Shared VPC environment with two Cloud Run services running in service projects and the ILB exposing them via a custom domain, pointing to them through a URL map: `/cart` and `/checkout`. + +

+ +For simplicity, both services are deployed in the same service project. Also, the blueprint uses an HTTP connection to the ILB to avoid management of SSL certificates. To test access, VMs are created in the host and service projects. Set the following in `terraform.tfvars`: + +```tfvars +prj_main_id = "[your-main-project-id]" # Used as host project +prj_svc1_id = "[your-service-project1-id]" +custom_domain = "cloud-run-corporate.example.org" +``` + +SSH into a test VM and run `curl` specifying as URL the host, your custom domain, and a path, `/cart` or `/checkout`. You will see each service responding to the request: + +

+ +Note that the default URLs for both services are also output, and the PSC endpoint for the `*.run.app` domain from previous examples is still created. However, access to these URLs from both VMs in the host or service project is blocked since the requests come from a VPC network in a different project to the service. + +## Cleaning up your environment + +The easiest way to remove all the deployed resources is to run the following command: +```bash +terraform destroy +``` +The above command will delete the associated resources so there will be no billable charges made afterwards. Projects are removed from Terraform state but not deleted from Google Cloud. + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [prj_main_id](variables.tf#L78) | Main Project ID. | string | ✓ | | +| [access_policy](variables.tf#L17) | VPC SC access policy, if it exists. | string | | null | +| [access_policy_create](variables.tf#L23) | Parameters for the creation of a VPC SC access policy. | object({…}) | | null | +| [custom_domain](variables.tf#L32) | Custom domain for the Load Balancer. | string | | null | +| [image](variables.tf#L38) | Container image to deploy. | string | | "us-docker.pkg.dev/cloudrun/container/hello" | +| [ingress_settings](variables.tf#L44) | Ingress traffic sources allowed to call the service. | string | | "internal" | +| [ip_ranges](variables.tf#L50) | IPs or IP ranges used by VPCs. | map(map(string)) | | {…} | +| [prj_main_create](variables.tf#L69) | Parameters for the creation of the main project. | object({…}) | | null | +| [prj_onprem_create](variables.tf#L83) | Parameters for the creation of an 'onprem' project. | object({…}) | | null | +| [prj_onprem_id](variables.tf#L92) | Onprem Project ID. | string | | null | +| [prj_prj1_create](variables.tf#L98) | Parameters for the creation of project 1. | object({…}) | | null | +| [prj_prj1_id](variables.tf#L107) | Project 1 ID. | string | | null | +| [prj_svc1_create](variables.tf#L113) | Parameters for the creation of service project 1. | object({…}) | | null | +| [prj_svc1_id](variables.tf#L122) | Service Project 1 ID. | string | | null | +| [region](variables.tf#L128) | Cloud region where resource will be deployed. | string | | "europe-west1" | +| [tf_identity](variables.tf#L134) | Terraform identity to include in VPC SC perimeter. | string | | null | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [default_URL_cart](outputs.tf#L17) | Cloud Run service 'cart' default URL. | | +| [default_URL_checkout](outputs.tf#L23) | Cloud Run service 'checkout' default URL. | | +| [default_URL_hello](outputs.tf#L29) | Cloud Run service 'hello' default URL. | | +| [load_balancer_ip](outputs.tf#L34) | Load Balancer IP address. | | + + +## Tests + +```hcl +module "test" { + source = "./fabric/blueprints/serverless/cloud-run-corporate" + prj_main_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" + } + prj_main_id = "main-project-id" # Used as host project + prj_onprem_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" + } + prj_onprem_id = "onprem-project-id" +} + +# tftest modules=15 resources=45 +``` + +```hcl +module "test" { + source = "./fabric/blueprints/serverless/cloud-run-corporate" + prj_main_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" + } + prj_main_id = "main-project-id" + prj_prj1_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" + } + prj_prj1_id = "project1-id" + access_policy = null + access_policy_create = { + parent = "organizations/0123456789" + title = "vpcsc-cloudrun" + } + tf_identity = "user@example.org" +} + +# tftest modules=15 resources=31 +``` + +```hcl +module "test" { + source = "./fabric/blueprints/serverless/cloud-run-corporate" + prj_main_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" + } + prj_main_id = "main-project-id" # Used as host project + prj_svc1_create = { + billing_account_id = "ABCDE-12345-ABCDE" + parent = "organizations/0123456789" + } + prj_svc1_id = "service-project1-id" + custom_domain = "cloud-run-corporate.example.org" +} + +# tftest modules=14 resources=38 +``` diff --git a/blueprints/serverless/cloud-run-corporate/images/service-running-1.png b/blueprints/serverless/cloud-run-corporate/images/service-running-1.png new file mode 100644 index 0000000000..7b883bf8e6 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/service-running-1.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/service-running-4.png b/blueprints/serverless/cloud-run-corporate/images/service-running-4.png new file mode 100644 index 0000000000..f1dfbc4c32 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/service-running-4.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-1.png b/blueprints/serverless/cloud-run-corporate/images/use-case-1.png new file mode 100644 index 0000000000..d851a3b713 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-1.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-2.png b/blueprints/serverless/cloud-run-corporate/images/use-case-2.png new file mode 100644 index 0000000000..7bce6a56a2 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-2.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-3.1.png b/blueprints/serverless/cloud-run-corporate/images/use-case-3.1.png new file mode 100644 index 0000000000..29a5186c87 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-3.1.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-3.2.png b/blueprints/serverless/cloud-run-corporate/images/use-case-3.2.png new file mode 100644 index 0000000000..e91d2ca063 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-3.2.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-3.3.png b/blueprints/serverless/cloud-run-corporate/images/use-case-3.3.png new file mode 100644 index 0000000000..32db625528 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-3.3.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-3.4.png b/blueprints/serverless/cloud-run-corporate/images/use-case-3.4.png new file mode 100644 index 0000000000..36f18be68f Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-3.4.png differ diff --git a/blueprints/serverless/cloud-run-corporate/images/use-case-4.png b/blueprints/serverless/cloud-run-corporate/images/use-case-4.png new file mode 100644 index 0000000000..afe86a1db6 Binary files /dev/null and b/blueprints/serverless/cloud-run-corporate/images/use-case-4.png differ diff --git a/blueprints/serverless/cloud-run-corporate/main.tf b/blueprints/serverless/cloud-run-corporate/main.tf new file mode 100644 index 0000000000..5eb98029c7 --- /dev/null +++ b/blueprints/serverless/cloud-run-corporate/main.tf @@ -0,0 +1,612 @@ +/** + * 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. + */ + +locals { + cloud_run_domain = "run.app." + service_name_cr1 = "cart" + service_name_cr2 = "checkout" + tf_id = (var.tf_identity == null ? null : + length(regexall("iam.gserviceaccount.com", var.tf_identity)) > 0 ? + "serviceAccount:${var.tf_identity}" : "user:${var.tf_identity}") + vpc_sc_create = (length(module.project_prj1) > 0 && + (var.access_policy != null || var.access_policy_create != null)) ? 1 : 0 +} + +############################################################################### +# Projects # +############################################################################### + +# Main project +module "project_main" { + source = "../../../modules/project" + name = var.prj_main_id + project_create = var.prj_main_create != null + billing_account = try(var.prj_main_create.billing_account_id, null) + parent = try(var.prj_main_create.parent, null) + # Enable Shared VPC by default, some use cases will use this project as host + shared_vpc_host_config = { + enabled = true + } + services = [ + "run.googleapis.com", + "compute.googleapis.com", + "dns.googleapis.com", + "cloudresourcemanager.googleapis.com", + "accesscontextmanager.googleapis.com" + ] + skip_delete = true +} + +# Simulated onprem environment +module "project_onprem" { + source = "../../../modules/project" + count = var.prj_onprem_id != null ? 1 : 0 + name = var.prj_onprem_id + project_create = var.prj_onprem_create != null + billing_account = try(var.prj_onprem_create.billing_account_id, null) + parent = try(var.prj_onprem_create.parent, null) + services = [ + "compute.googleapis.com", + "dns.googleapis.com" + ] + skip_delete = true +} + +# Project 1 +module "project_prj1" { + source = "../../../modules/project" + count = var.prj_prj1_id != null ? 1 : 0 + name = var.prj_prj1_id + project_create = var.prj_prj1_create != null + billing_account = try(var.prj_prj1_create.billing_account_id, null) + parent = try(var.prj_prj1_create.parent, null) + services = [ + "compute.googleapis.com", + "dns.googleapis.com" + ] + skip_delete = true +} + +# Service Project 1 +module "project_svc1" { + source = "../../../modules/project" + count = var.prj_svc1_id != null ? 1 : 0 + name = var.prj_svc1_id + project_create = var.prj_svc1_create != null + billing_account = try(var.prj_svc1_create.billing_account_id, null) + parent = try(var.prj_svc1_create.parent, null) + shared_vpc_service_config = { + host_project = module.project_main.project_id + } + services = [ + "compute.googleapis.com", + "dns.googleapis.com", + "run.googleapis.com" + ] + skip_delete = true +} + +############################################################################### +# Cloud Run # +############################################################################### + +# Cloud Run service in main project +module "cloud_run_hello" { + source = "../../../modules/cloud-run" + project_id = module.project_main.project_id + name = "hello" + region = var.region + containers = [{ + image = var.image + options = null + ports = null + resources = null + volume_mounts = null + }] + iam = { + "roles/run.invoker" = ["allUsers"] + } + ingress_settings = var.ingress_settings +} + +# Cloud Run service 1 in service project +module "cloud_run_cart" { + source = "../../../modules/cloud-run" + count = var.custom_domain == null ? 0 : 1 + project_id = module.project_svc1[0].project_id + name = local.service_name_cr1 # "cart" + region = var.region + containers = [{ + image = var.image + options = null + ports = null + resources = null + volume_mounts = null + }] + iam = { + "roles/run.invoker" = ["allUsers"] + } + ingress_settings = var.ingress_settings +} + +# Cloud Run service 2 in service project +module "cloud_run_checkout" { + source = "../../../modules/cloud-run" + count = var.custom_domain == null ? 0 : 1 + project_id = module.project_svc1[0].project_id + name = local.service_name_cr2 # "checkout" + region = var.region + containers = [{ + image = var.image + options = null + ports = null + resources = null + volume_mounts = null + }] + iam = { + "roles/run.invoker" = ["allUsers"] + } + ingress_settings = var.ingress_settings +} + +############################################################################### +# VPCs # +############################################################################### + +# VPC in main project +module "vpc_main" { + source = "../../../modules/net-vpc" + project_id = module.project_main.project_id + name = "vpc-main" + subnets = [ + { + ip_cidr_range = var.ip_ranges["main"].subnet + name = "subnet-main" + region = var.region + } + ] + subnets_proxy_only = [ + { + ip_cidr_range = var.ip_ranges["main"].subnet_proxy + name = "subnet-proxy" + region = var.region + active = true + } + ] +} + +# Main VPC Firewall with default config, IAP for SSH enabled +module "firewall_main" { + source = "../../../modules/net-vpc-firewall" + project_id = module.project_main.project_id + network = module.vpc_main.name + default_rules_config = { + http_ranges = [] + https_ranges = [] + } +} + +# VPC in simulated onprem environment +module "vpc_onprem" { + source = "../../../modules/net-vpc" + count = length(module.project_onprem) + project_id = module.project_onprem[0].project_id + name = "vpc-onprem" + subnets = [ + { + ip_cidr_range = var.ip_ranges["onprem"].subnet + name = "subnet-onprem" + region = var.region + } + ] +} + +# Onprem VPC Firewall with default config, IAP for SSH enabled +module "firewall_onprem" { + source = "../../../modules/net-vpc-firewall" + count = length(module.project_onprem) + project_id = module.project_onprem[0].project_id + network = module.vpc_onprem[0].name + default_rules_config = { + http_ranges = [] + https_ranges = [] + } +} + +# VPC in project 1 +module "vpc_prj1" { + source = "../../../modules/net-vpc" + count = length(module.project_prj1) + project_id = module.project_prj1[0].project_id + name = "vpc-prj1" + subnets = [ + { + ip_cidr_range = var.ip_ranges["prj1"].subnet + name = "subnet-prj1" + region = var.region + } + ] +} + +# Project 1 VPC Firewall with default config, IAP for SSH enabled +module "firewall_prj1" { + source = "../../../modules/net-vpc-firewall" + count = length(module.project_prj1) + project_id = module.project_prj1[0].project_id + network = module.vpc_prj1[0].name + default_rules_config = { + http_ranges = [] + https_ranges = [] + } +} + +############################################################################### +# PSC # +############################################################################### + +# PSC configured in the main project +module "psc_addr_main" { + source = "../../../modules/net-address" + project_id = module.project_main.project_id + psc_addresses = { + psc-addr = { + address = var.ip_ranges["main"].psc_addr + network = module.vpc_main.self_link + } + } +} + +resource "google_compute_global_forwarding_rule" "psc_endpoint_main" { + provider = google-beta + project = module.project_main.project_id + name = "pscaddr" + network = module.vpc_main.self_link + ip_address = module.psc_addr_main.psc_addresses["psc-addr"].self_link + target = "vpc-sc" + load_balancing_scheme = "" +} + +# PSC configured in project 1 +module "psc_addr_prj1" { + source = "../../../modules/net-address" + count = length(module.project_prj1) + project_id = module.project_prj1[0].project_id + psc_addresses = { + psc-addr = { + address = var.ip_ranges["prj1"].psc_addr + network = module.vpc_prj1[0].self_link + } + } +} + +resource "google_compute_global_forwarding_rule" "psc_endpoint_prj1" { + provider = google-beta + count = length(module.project_prj1) + project = module.project_prj1[0].project_id + name = "pscaddr" + network = module.vpc_prj1[0].self_link + ip_address = module.psc_addr_prj1[0].psc_addresses["psc-addr"].self_link + target = "vpc-sc" + load_balancing_scheme = "" +} + +############################################################################### +# L7 ILB # +############################################################################### + +module "ilb-l7" { + source = "../../../modules/net-ilb-l7" + count = var.custom_domain == null ? 0 : 1 + project_id = module.project_main.project_id + name = "ilb-l7-cr" + region = var.region + backend_service_configs = { + default = { + project_id = module.project_svc1[0].project_id + backends = [{ + group = "cr1" + }] + health_checks = [] + } + cart = { + project_id = module.project_svc1[0].project_id + backends = [{ + group = "cr1" + }] + health_checks = [] + } + checkout = { + project_id = module.project_svc1[0].project_id + backends = [{ + group = "cr2" + }] + health_checks = [] + } + } + health_check_configs = {} + neg_configs = { + cr1 = { + project_id = module.project_svc1[0].project_id + cloudrun = { + region = var.region + target_service = { + name = local.service_name_cr1 + } + } + } + cr2 = { + project_id = module.project_svc1[0].project_id + cloudrun = { + region = var.region + target_service = { + name = local.service_name_cr2 + } + } + } + } + urlmap_config = { + default_service = "default" + host_rules = [{ + hosts = ["*"] + path_matcher = "pathmap" + }] + path_matchers = { + pathmap = { + default_service = "default" + path_rules = [ + { + paths = ["/cart", "/cart/*"] + service = local.service_name_cr1 + }, + { + paths = ["/checkout", "/checkout/*"] + service = local.service_name_cr2 + } + ] + } + } + } + vpc_config = { + network = module.vpc_main.self_link + subnetwork = module.vpc_main.subnet_self_links["${var.region}/subnet-main"] + } +} + +############################################################################### +# VMs # +############################################################################### + +module "vm_test_main" { + source = "../../../modules/compute-vm" + project_id = module.project_main.project_id + zone = "${var.region}-b" + name = "vm-test-main" + instance_type = "e2-micro" + network_interfaces = [{ + network = module.vpc_main.self_link + subnetwork = module.vpc_main.subnet_self_links["${var.region}/subnet-main"] + }] + tags = ["ssh"] +} + +module "vm_test_onprem" { + source = "../../../modules/compute-vm" + count = length(module.project_onprem) + project_id = module.project_onprem[0].project_id + zone = "${var.region}-b" + name = "vm-test-onprem" + instance_type = "e2-micro" + network_interfaces = [{ + network = module.vpc_onprem[0].self_link + subnetwork = module.vpc_onprem[0].subnet_self_links["${var.region}/subnet-onprem"] + }] + tags = ["ssh"] +} + +module "vm_test_prj1" { + source = "../../../modules/compute-vm" + count = length(module.project_prj1) + project_id = module.project_prj1[0].project_id + zone = "${var.region}-b" + name = "vm-test-prj1" + instance_type = "e2-micro" + network_interfaces = [{ + network = module.vpc_prj1[0].self_link + subnetwork = module.vpc_prj1[0].subnet_self_links["${var.region}/subnet-prj1"] + }] + tags = ["ssh"] +} + +module "vm_test_svc1" { + source = "../../../modules/compute-vm" + count = length(module.project_svc1) + project_id = module.project_svc1[0].project_id + zone = "${var.region}-b" + name = "vm-test-svc1" + instance_type = "e2-micro" + network_interfaces = [{ + network = module.vpc_main.self_link + subnetwork = module.vpc_main.subnet_self_links["${var.region}/subnet-main"] + }] + tags = ["ssh"] +} + +############################################################################### +# DNS # +############################################################################### + +module "private_dns_main" { + source = "../../../modules/dns" + project_id = module.project_main.project_id + type = "private" + name = "dns-main" + client_networks = [module.vpc_main.self_link] + domain = local.cloud_run_domain + recordsets = { + "A *" = { records = [module.psc_addr_main.psc_addresses["psc-addr"].address] } + } +} + +module "private_dns_main_custom" { + source = "../../../modules/dns" + count = var.custom_domain == null ? 0 : 1 + project_id = module.project_main.project_id + type = "private" + name = "dns-main-custom" + client_networks = [module.vpc_main.self_link] + domain = format("%s.", var.custom_domain) + recordsets = { + "A " = { records = [module.ilb-l7[0].address] } + } +} + +module "private_dns_onprem" { + source = "../../../modules/dns" + count = length(module.project_onprem) + project_id = module.project_onprem[0].project_id + type = "private" + name = "dns-onprem" + client_networks = [module.vpc_onprem[0].self_link] + domain = local.cloud_run_domain + recordsets = { + "A *" = { records = [module.psc_addr_main.psc_addresses["psc-addr"].address] } + } +} + +module "private_dns_prj1" { + source = "../../../modules/dns" + count = length(module.project_prj1) + project_id = module.project_prj1[0].project_id + type = "private" + name = "dns-prj1" + client_networks = [module.vpc_prj1[0].self_link] + domain = local.cloud_run_domain + recordsets = { + "A *" = { records = [module.psc_addr_prj1[0].psc_addresses["psc-addr"].address] } + } +} + +############################################################################### +# VPC SC # +############################################################################### + +module "vpc_sc" { + source = "../../../modules/vpc-sc" + count = local.vpc_sc_create + access_policy = var.access_policy_create == null ? var.access_policy : null + access_policy_create = var.access_policy_create + ingress_policies = { + ingress-ids = { + from = { + identities = [local.tf_id] + access_levels = ["*"] + } + to = { + operations = [{ service_name = "*" }] + resources = ["*"] + } + } + } + service_perimeters_regular = { + cloudrun = { + status = { + resources = [ + "projects/${module.project_main.number}", + "projects/${module.project_prj1[0].number}" + ] + restricted_services = ["run.googleapis.com"] + ingress_policies = ["ingress-ids"] + } + } + } +} + +############################################################################### +# VPN # +############################################################################### + +# VPN between main project and "onprem" environment +module "vpn_main" { + source = "../../../modules/net-vpn-ha" + count = length(module.project_onprem) + project_id = module.project_main.project_id + region = var.region + network = module.vpc_main.self_link + name = "vpn-main-to-onprem" + peer_gateways = { + default = { gcp = module.vpn_onprem[0].self_link } + } + router_config = { + asn = 65001 + custom_advertise = { + all_subnets = true + ip_ranges = { + (var.ip_ranges["main"].psc_addr) = "to-psc-endpoint" + } + } + } + tunnels = { + tunnel-0 = { + bgp_peer = { + address = "169.254.0.2" + asn = 65002 + } + bgp_session_range = "169.254.0.1/30" + vpn_gateway_interface = 0 + } + tunnel-1 = { + bgp_peer = { + address = "169.254.1.2" + asn = 65002 + } + bgp_session_range = "169.254.1.1/30" + vpn_gateway_interface = 1 + } + } +} + +module "vpn_onprem" { + source = "../../../modules/net-vpn-ha" + count = length(module.project_onprem) + project_id = module.project_onprem[0].project_id + region = var.region + network = module.vpc_onprem[0].self_link + name = "vpn-onprem-to-main" + peer_gateways = { + default = { gcp = module.vpn_main[0].self_link } + } + router_config = { asn = 65002 } + tunnels = { + tunnel-0 = { + bgp_peer = { + address = "169.254.0.1" + asn = 65001 + } + bgp_session_range = "169.254.0.2/30" + vpn_gateway_interface = 0 + shared_secret = module.vpn_main[0].random_secret + } + tunnel-1 = { + bgp_peer = { + address = "169.254.1.1" + asn = 65001 + } + bgp_session_range = "169.254.1.2/30" + vpn_gateway_interface = 1 + shared_secret = module.vpn_main[0].random_secret + } + } +} diff --git a/blueprints/serverless/cloud-run-corporate/outputs.tf b/blueprints/serverless/cloud-run-corporate/outputs.tf new file mode 100644 index 0000000000..6ffef14103 --- /dev/null +++ b/blueprints/serverless/cloud-run-corporate/outputs.tf @@ -0,0 +1,37 @@ +/** + * 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. + */ + +output "default_URL_cart" { + description = "Cloud Run service 'cart' default URL." + value = (var.custom_domain != null ? + module.cloud_run_cart[0].service.status[0].url : "none") +} + +output "default_URL_checkout" { + description = "Cloud Run service 'checkout' default URL." + value = (var.custom_domain != null ? + module.cloud_run_checkout[0].service.status[0].url : "none") +} + +output "default_URL_hello" { + description = "Cloud Run service 'hello' default URL." + value = module.cloud_run_hello.service.status[0].url +} + +output "load_balancer_ip" { + description = "Load Balancer IP address." + value = var.custom_domain != null ? module.ilb-l7[0].address : "none" +} diff --git a/tests/blueprints/cloud_operations/packer_image_builder/fixture/variables.tf b/blueprints/serverless/cloud-run-corporate/provider.tf similarity index 82% rename from tests/blueprints/cloud_operations/packer_image_builder/fixture/variables.tf rename to blueprints/serverless/cloud-run-corporate/provider.tf index 5320fb690b..bb8c9f664a 100644 --- a/tests/blueprints/cloud_operations/packer_image_builder/fixture/variables.tf +++ b/blueprints/serverless/cloud-run-corporate/provider.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -variable "create_packer_vars" { - type = bool - default = false +provider "google" { + user_project_override = true + billing_project = var.prj_main_id } diff --git a/blueprints/serverless/cloud-run-corporate/variables.tf b/blueprints/serverless/cloud-run-corporate/variables.tf new file mode 100644 index 0000000000..c86c6784a2 --- /dev/null +++ b/blueprints/serverless/cloud-run-corporate/variables.tf @@ -0,0 +1,138 @@ +/** + * 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. + */ + +variable "access_policy" { + description = "VPC SC access policy, if it exists." + type = string + default = null +} + +variable "access_policy_create" { + description = "Parameters for the creation of a VPC SC access policy." + type = object({ + parent = string + title = string + }) + default = null +} + +variable "custom_domain" { + description = "Custom domain for the Load Balancer." + type = string + default = null +} + +variable "image" { + description = "Container image to deploy." + type = string + default = "us-docker.pkg.dev/cloudrun/container/hello" +} + +variable "ingress_settings" { + description = "Ingress traffic sources allowed to call the service." + type = string + default = "internal" +} + +variable "ip_ranges" { + description = "IPs or IP ranges used by VPCs." + type = map(map(string)) + default = { + main = { + subnet = "10.0.1.0/24" + subnet_proxy = "10.10.0.0/24" + psc_addr = "10.0.0.100" + } + onprem = { + subnet = "172.16.1.0/24" + } + prj1 = { + subnet = "10.0.2.0/24" + psc_addr = "10.0.0.200" + } + } +} + +variable "prj_main_create" { + description = "Parameters for the creation of the main project." + type = object({ + billing_account_id = string + parent = string + }) + default = null +} + +variable "prj_main_id" { + description = "Main Project ID." + type = string +} + +variable "prj_onprem_create" { + description = "Parameters for the creation of an 'onprem' project." + type = object({ + billing_account_id = string + parent = string + }) + default = null +} + +variable "prj_onprem_id" { + description = "Onprem Project ID." + type = string + default = null +} + +variable "prj_prj1_create" { + description = "Parameters for the creation of project 1." + type = object({ + billing_account_id = string + parent = string + }) + default = null +} + +variable "prj_prj1_id" { + description = "Project 1 ID." + type = string + default = null +} + +variable "prj_svc1_create" { + description = "Parameters for the creation of service project 1." + type = object({ + billing_account_id = string + parent = string + }) + default = null +} + +variable "prj_svc1_id" { + description = "Service Project 1 ID." + type = string + default = null +} + +variable "region" { + description = "Cloud region where resource will be deployed." + type = string + default = "europe-west1" +} + +variable "tf_identity" { + description = "Terraform identity to include in VPC SC perimeter." + type = string + default = null +} diff --git a/blueprints/serverless/cloud-run-explore/README.md b/blueprints/serverless/cloud-run-explore/README.md index 1002e817e5..b88d4f9cad 100644 --- a/blueprints/serverless/cloud-run-explore/README.md +++ b/blueprints/serverless/cloud-run-explore/README.md @@ -2,10 +2,14 @@ ## Introduction -This blueprint contains all the necessary Terraform modules to build and publicly expose a Cloud Run service in a variety of use cases. +This blueprint contains all the necessary Terraform modules to build and __publicly__ expose Cloud Run services in a variety of use cases. The content of this blueprint corresponds to the chapter '_My serverless "Hello, World! - Exploring Cloud Run_' of the __Serverless Networking Guide__ (to be released soon). This guide is an easy to follow introduction to Cloud Run, where a couple of friendly characters will guide you from the basics to more advanced topics with a very practical approach and in record time! The code here complements this learning and allows you to test the scenarios presented and your knowledge. +If you are interested in following this guide, take a look to the chapters' blueprints: +* [My serverless "Hello, World! - Exploring Cloud Run](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/master/blueprints/serverless/cloud-run-explore) +* [Developing an enterprise application - The corporate environment](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/master/blueprints/serverless/cloud-run-corporate) + ## Architecture The following diagram depicts the main components that this blueprint will set up: @@ -211,4 +215,4 @@ module "test" { } # tftest modules=4 resources=17 -``` \ No newline at end of file +``` diff --git a/blueprints/third-party-solutions/openshift/tf/versions.tf b/blueprints/third-party-solutions/openshift/tf/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/third-party-solutions/openshift/tf/versions.tf +++ b/blueprints/third-party-solutions/openshift/tf/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/default-versions.tf b/default-versions.tf index 08492c6f95..cef924ea40 100644 --- a/default-versions.tf +++ b/default-versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/fast/extras/0-cicd-github/README.md b/fast/extras/0-cicd-github/README.md index 58407b5e4e..0bd0b5be1d 100644 --- a/fast/extras/0-cicd-github/README.md +++ b/fast/extras/0-cicd-github/README.md @@ -39,6 +39,16 @@ modules_config = { # tftest skip ``` +If the modules are located in a non modules only repository, use the module_prefix attribute to set the location of your modules within the repository: + +```hcl +modules_config = { + repository_name = "GoogleCloudPlatform/cloud-foundation-fabric" + module_prefix = "modules/" +} +# tftest skip +``` + In the above example, no key options are set so it's assumed modules will be fetched from a public repository. If modules repository authentication is needed the `key_config` attribute also needs to be set. If no keypair path is specified an internally generated key will be stored as an access key in the modules repository, and as secrets in the stage repositories: @@ -125,10 +135,10 @@ Finally, a `commit_config` variable is optional: it can be used to configure aut | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [organization](variables.tf#L50) | GitHub organization. | string | ✓ | | +| [organization](variables.tf#L51) | GitHub organization. | string | ✓ | | | [commmit_config](variables.tf#L17) | Configure commit metadata. | object({…}) | | {} | -| [modules_config](variables.tf#L28) | Configure access to repository module via key, and replacement for modules sources in stage repositories. | object({…}) | | null | -| [repositories](variables.tf#L55) | Repositories to create. | map(object({…})) | | {} | +| [modules_config](variables.tf#L28) | Configure access to repository module via key, and replacement for modules sources in stage repositories. | object({…}) | | null | +| [repositories](variables.tf#L56) | Repositories to create. | map(object({…})) | | {} | ## Outputs diff --git a/fast/extras/0-cicd-github/main.tf b/fast/extras/0-cicd-github/main.tf index d91ab970c5..3c42b5cf6d 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}/*.svg") : f], [for f in fileset(path.module, "${v.populate_from}/*.md") : f], [for f in fileset(path.module, "${v.populate_from}/*.tf") : f] ) : { @@ -32,7 +33,8 @@ locals { ? "" : "?ref=${var.modules_config.source_ref}" ) - modules_repo = try(var.modules_config.repository_name, null) + modules_repo = try(var.modules_config.repository_name, null) + module_prefix = try(var.modules_config.module_prefix, null) repositories = { for k, v in var.repositories : k => v.create_options == null ? k : github_repository.default[k].name @@ -143,8 +145,8 @@ resource "github_repository_file" "default" { endswith(each.value.name, ".tf") && local.modules_repo != null ? replace( file(each.value.file), - "/source\\s*=\\s*\"../../../modules/([^/\"]+)\"/", - "source = \"git@github.com:${local.modules_repo}.git//$1${local.modules_ref}\"" # " + "/source(\\s*)=\\s*\"../../../modules/([^/\"]+)\"/", + "source$1= \"git@github.com:${local.modules_repo}.git//${local.module_prefix}$2${local.modules_ref}\"" # " ) : file(each.value.file) ) diff --git a/fast/extras/0-cicd-github/variables.tf b/fast/extras/0-cicd-github/variables.tf index 8e5d0832ff..ea378ee789 100644 --- a/fast/extras/0-cicd-github/variables.tf +++ b/fast/extras/0-cicd-github/variables.tf @@ -30,6 +30,7 @@ variable "modules_config" { type = object({ repository_name = string source_ref = optional(string) + module_prefix = optional(string, "") key_config = optional(object({ create_key = optional(bool, false) create_secrets = optional(bool, false) diff --git a/fast/stage-links.sh b/fast/stage-links.sh index 79d1973fa1..52c9e5ae6d 100755 --- a/fast/stage-links.sh +++ b/fast/stage-links.sh @@ -78,6 +78,11 @@ case $STAGE_NAME in TFVARS="tfvars/0-bootstrap.auto.tfvars.json tfvars/1-resman.auto.tfvars.json" ;; +"2-security"*) + PROVIDER="providers/2-security-providers.tf" + TFVARS="tfvars/0-bootstrap.auto.tfvars.json + tfvars/1-resman.auto.tfvars.json" + ;; *) # check for a "dev" stage 3 echo "no stage found, trying for parent stage 3..." diff --git a/fast/stages-multitenant/1-resman-tenant/branch-sandbox.tf b/fast/stages-multitenant/1-resman-tenant/branch-sandbox.tf index 6f3d526c85..39ab03ed7f 100644 --- a/fast/stages-multitenant/1-resman-tenant/branch-sandbox.tf +++ b/fast/stages-multitenant/1-resman-tenant/branch-sandbox.tf @@ -28,8 +28,8 @@ module "branch-sandbox-folder" { "roles/resourcemanager.projectCreator" = [local.automation_sas_iam.sandbox] } org_policies = { - "constraints/sql.restrictPublicIp" = { enforce = false } - "constraints/compute.vmExternalIpAccess" = { allow = { all = true } } + "sql.restrictPublicIp" = { rules = [{ enforce = false }] } + "compute.vmExternalIpAccess" = { rules = [{ allow = { all = true } }] } } tag_bindings = { context = var.tags.values["${var.tags.names.context}/sandbox"] diff --git a/fast/stages-multitenant/1-resman-tenant/data/org-policies/compute.yaml b/fast/stages-multitenant/1-resman-tenant/data/org-policies/compute.yaml index 0d27ac426d..a3f96b1b1c 100644 --- a/fast/stages-multitenant/1-resman-tenant/data/org-policies/compute.yaml +++ b/fast/stages-multitenant/1-resman-tenant/data/org-policies/compute.yaml @@ -3,71 +3,90 @@ # sample subset of useful organization policies, edit to suit requirements compute.disableGuestAttributesAccess: - enforce: true + rules: + - enforce: true compute.requireOsLogin: - enforce: true + rules: + - enforce: true compute.restrictLoadBalancerCreationForTypes: - allow: - values: - - in:INTERNAL + rules: + - allow: + values: + - in:INTERNAL compute.skipDefaultNetworkCreation: - enforce: true + rules: + - enforce: true compute.vmExternalIpAccess: - deny: - all: true + rules: + - deny: + all: true # compute.disableInternetNetworkEndpointGroup: -# enforce: true +# rules: +# - enforce: true # compute.disableNestedVirtualization: -# enforce: true +# rules: +# - enforce: true # compute.disableSerialPortAccess: -# enforce: true +# rules: +# - enforce: true # compute.restrictCloudNATUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictDedicatedInterconnectUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictPartnerInterconnectUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictProtocolForwardingCreationForTypes: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictSharedVpcHostProjects: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictSharedVpcSubnetworks: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictVpcPeering: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictVpnPeerIPs: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictXpnProjectLienRemoval: -# enforce: true +# rules: +# - enforce: true # compute.setNewProjectDefaultToZonalDNSOnly: -# enforce: true +# rules: +# - enforce: true # compute.vmCanIpForward: -# deny: -# all: true +# rules: +# - deny: +# all: true diff --git a/fast/stages-multitenant/1-resman-tenant/data/org-policies/iam.yaml b/fast/stages-multitenant/1-resman-tenant/data/org-policies/iam.yaml index 4d83f827fe..58e0032cb3 100644 --- a/fast/stages-multitenant/1-resman-tenant/data/org-policies/iam.yaml +++ b/fast/stages-multitenant/1-resman-tenant/data/org-policies/iam.yaml @@ -3,10 +3,13 @@ # sample subset of useful organization policies, edit to suit requirements iam.automaticIamGrantsForDefaultServiceAccounts: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyCreation: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyUpload: - enforce: true + rules: + - enforce: true diff --git a/fast/stages-multitenant/1-resman-tenant/data/org-policies/serverless.yaml b/fast/stages-multitenant/1-resman-tenant/data/org-policies/serverless.yaml index de62e6c702..3efb23cdee 100644 --- a/fast/stages-multitenant/1-resman-tenant/data/org-policies/serverless.yaml +++ b/fast/stages-multitenant/1-resman-tenant/data/org-policies/serverless.yaml @@ -3,24 +3,29 @@ # sample subset of useful organization policies, edit to suit requirements run.allowedIngress: - allow: - values: - - is:internal + rules: + - allow: + values: + - is:internal # run.allowedVPCEgress: -# allow: -# values: +# rules: +# - allow: +# values: # - is:private-ranges-only # cloudfunctions.allowedIngressSettings: -# allow: -# values: -# - is:ALLOW_INTERNAL_ONLY +# rules: +# - allow: +# values: +# - is:ALLOW_INTERNAL_ONLY # cloudfunctions.allowedVpcConnectorEgressSettings: -# allow: -# values: -# - is:PRIVATE_RANGES_ONLY +# rules: +# - allow: +# values: +# - is:PRIVATE_RANGES_ONLY # cloudfunctions.requireVPCConnector: -# enforce: true +# rules: +# - enforce: true diff --git a/fast/stages-multitenant/1-resman-tenant/data/org-policies/sql.yaml b/fast/stages-multitenant/1-resman-tenant/data/org-policies/sql.yaml index 88b84d9d50..0eee80453a 100644 --- a/fast/stages-multitenant/1-resman-tenant/data/org-policies/sql.yaml +++ b/fast/stages-multitenant/1-resman-tenant/data/org-policies/sql.yaml @@ -3,7 +3,9 @@ # sample subset of useful organization policies, edit to suit requirements sql.restrictAuthorizedNetworks: - enforce: true + rules: + - enforce: true sql.restrictPublicIp: - enforce: true + rules: + - enforce: true diff --git a/fast/stages-multitenant/1-resman-tenant/data/org-policies/storage.yaml b/fast/stages-multitenant/1-resman-tenant/data/org-policies/storage.yaml index 6c0a673f3a..448357b8bc 100644 --- a/fast/stages-multitenant/1-resman-tenant/data/org-policies/storage.yaml +++ b/fast/stages-multitenant/1-resman-tenant/data/org-policies/storage.yaml @@ -3,4 +3,5 @@ # sample subset of useful organization policies, edit to suit requirements storage.uniformBucketLevelAccess: - enforce: true + rules: + - enforce: true diff --git a/fast/stages/0-bootstrap/README.md b/fast/stages/0-bootstrap/README.md index 2cab11510d..88bdceb3fb 100644 --- a/fast/stages/0-bootstrap/README.md +++ b/fast/stages/0-bootstrap/README.md @@ -14,6 +14,28 @@ Use the following diagram as a simple high level reference for the following sec Organization-level diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [User groups](#user-groups) + - [Organization-level IAM](#organization-level-iam) + - [Automation project and resources](#automation-project-and-resources) + - [Billing account](#billing-account) + - [Organization-level logging](#organization-level-logging) + - [Naming](#naming) + - [Workload Identity Federation and CI/CD](#workload-identity-federation-and-cicd) +- [How to run this stage](#how-to-run-this-stage) + - [Prerequisites](#prerequisites) + - [Output files and cross-stage variables](#output-files-and-cross-stage-variables) + - [Running the stage](#running-the-stage) +- [Customizations](#customizations) + - [Group names](#group-names) + - [IAM](#iam) + - [Log sinks and log destinations](#log-sinks-and-log-destinations) + - [Names and naming convention](#names-and-naming-convention) + - [Workload Identity Federation](#workload-identity-federation) + - [CI/CD repositories](#cicd-repositories) + ## Design overview and choices As mentioned above, this stage only does the bare minimum required to bootstrap automation, and ensure that base audit and billing exports are in place from the start to provide some measure of accountability, even before the security configurations are applied in a later stage. @@ -80,7 +102,7 @@ The convention is used in its full form only for specific resources with globall The [Customizations](#names-and-naming-convention) section on names below explains how to configure tokens, or implement a different naming convention. -## Workload Identity Federation and CI/CD +### Workload Identity Federation and CI/CD This stage also implements initial support for two interrelated features @@ -124,7 +146,7 @@ To quickly self-grant the above roles, run the following code snippet as the ini export FAST_BU=$(gcloud config list --format 'value(core.account)') # find and set your org id -gcloud organizations list --filter display_name:$partofyourdomain +gcloud organizations list export FAST_ORG_ID=123456 # set needed roles @@ -139,25 +161,6 @@ done Then make sure the same user is also part of the `gcp-organization-admins` group so that impersonating the automation service account later on will be possible. -#### Billing account in a different organization - -If you are using a billing account belonging to a different organization (e.g. in multiple organization setups), some initial configurations are needed to ensure the identities running this stage can assign billing-related roles. - -If the billing organization is managed by another version of this stage, we leverage the `organizationIamAdmin` role created there, to allow restricted granting of billing roles at the organization level. - -If that's not the case, an equivalent role needs to exist, or the predefined `resourcemanager.organizationAdmin` role can be used if not managed authoritatively. The role name then needs to be manually changed in the `billing.tf` file, in the `google_organization_iam_binding` resource. - -The identity applying this stage for the first time also needs two roles in billing organization, they can be removed after the first `apply` completes successfully: - -```bash -export FAST_BILLING_ORG_ID=789012 -export FAST_ROLES=(roles/billing.admin roles/resourcemanager.organizationAdmin) -for role in $FAST_ROLES; do - gcloud organizations add-iam-policy-binding $FAST_BILLING_ORG_ID \ - --member user:$FAST_BU --role $role -done -``` - #### Standalone billing account If you are using a standalone billing account, the identity applying this stage for the first time needs to be a billing account administrator: @@ -187,7 +190,7 @@ Please note that FAST also supports an additional group for users with permissio Then make sure you have configured the correct values for the following variables by providing a `terraform.tfvars` file: - `billing_account` - an object containing `id` as the id of your billing account, derived from the Cloud Console UI or by running `gcloud beta billing accounts list`, and `organization_id` as the id of the organization owning it, or `null` to use the billing account in isolation + an object containing `id` as the id of your billing account, derived from the Cloud Console UI or by running `gcloud beta billing accounts list`, and the `is_org_level` flag that controls whether organization or account-level bindings are used, and a billing export project and dataset are created - `groups` the name mappings for your groups, if you're following the default convention you can leave this to the provided default - `organization.id`, `organization.domain`, `organization.customer_id` @@ -202,7 +205,6 @@ You can also adapt the example that follows to your needs: # if you have too many accounts, check the Cloud Console :) billing_account = { id = "012345-67890A-BCDEF0" - organization_id = 1234567890 } # use `gcloud organizations list` @@ -237,18 +239,18 @@ Below is the outline of the output files generated by all stages, which is ident ```bash [path specified in outputs_location] ├── providers -│   ├── 00-bootstrap-providers.tf -│   ├── 01-resman-providers.tf -│   ├── 02-networking-providers.tf -│   ├── 02-security-providers.tf -│   ├── 03-project-factory-dev-providers.tf -│   ├── 03-project-factory-prod-providers.tf -│   └── 99-sandbox-providers.tf +│   ├── 0-bootstrap-providers.tf +│   ├── 1-resman-providers.tf +│   ├── 2-networking-providers.tf +│   ├── 2-security-providers.tf +│   ├── 3-project-factory-dev-providers.tf +│   ├── 3-project-factory-prod-providers.tf +│   └── 9-sandbox-providers.tf └── tfvars -│ ├── 00-bootstrap.auto.tfvars.json -│ ├── 01-resman.auto.tfvars.json -│ ├── 02-networking.auto.tfvars.json -│ └── 02-security.auto.tfvars.json +│ ├── 0-bootstrap.auto.tfvars.json +│ ├── 1-resman.auto.tfvars.json +│ ├── 2-networking.auto.tfvars.json +│ └── 2-security.auto.tfvars.json └── workflows └── [optional depending on the configured CI/CD repositories] ``` @@ -267,17 +269,34 @@ terraform apply \ > If you see an error related to project name already exists, please make sure the project name is unique or the project was not deleted recently -Once the initial `apply` completes successfully, configure a remote backend using the new GCS bucket, and impersonation on the automation service account for this stage. To do this you can use the generated `providers.tf` file if you have configured output files as described above, or extract its contents from Terraform's output, then migrate state with `terraform init`: +Once the initial `apply` completes successfully, configure a remote backend using the new GCS bucket, and impersonation on the automation service account for this stage. To do this you can use the generated `providers.tf` file from either + +- the local filesystem if you have configured output files as described above +- the GCS bucket where output files are always stored +- Terraform outputs (not recommended as it's more complex) + +The following two snippets show how to leverage the `stage-links.sh` script in the root FAST folder to fetch the commands required for output files linking or copying, using either the local output folder configured via Terraform variables, or the GCS bucket which can be derived from the `automation` output. + +```bash +../../stage-links.sh ~/fast-config + +# copy and paste the following commands for '0-bootstrap' + +ln -s ~/fast-config/providers/0-bootstrap-providers.tf ./ +``` + +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '0-bootstrap' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/0-bootstrap-providers.tf ./ +``` + +Copy/paste the command returned by the script to link or copy the provider file, then migrate state with `terraform init` and run `terraform apply`: ```bash -# if using output files via the outputs_location and set to `~/fast-config` -ln -s ~/fast-config/providers/00-bootstrap* ./ -# or from outputs if not using output files -terraform output -json providers | jq -r '.["00-bootstrap"]' \ - > providers.tf -# migrate state to GCS bucket configured in providers file terraform init -migrate-state -# run terraform apply to remove the bootstrap_user iam binding terraform apply ``` @@ -334,7 +353,7 @@ You can customize organization-level logs through the `log_sinks` variable in tw - creating additional log sinks to capture more logs - changing the destination of captured logs -By default, all logs are exported to Bigquery, but FAST can create sinks to Cloud Logging Buckets, GCS, or PubSub. +By default, all logs are exported to a log bucket, but FAST can create sinks to BigQuery, GCS, or PubSub. If you need to capture additional logs, please refer to GCP's documentation on [scenarios for exporting logging data](https://cloud.google.com/architecture/exporting-stackdriver-logging-for-security-and-access-analytics), where you can find ready-made filter expressions for different use cases. @@ -400,12 +419,6 @@ cicd_repositories = { name = "my-gh-org/fast-bootstrap" type = "github" } - cicd = { - branch = null - identity_provider = "github-sample" - name = "my-gh-org/fast-cicd" - type = "github" - } resman = { branch = "main" identity_provider = "github-sample" @@ -439,7 +452,10 @@ The remaining configuration is manual, as it regards the repositories themselves - edit the modules source to match your modules repository - a simple way is using the "Replace in files" function of your editor - search for `source\s*= "../../../modules/([^"]+)"` - - replace with `source = "git@github.com:my-org/fast-modules.git//$1?ref=v1.0"` + - replace with: + - modules stored on GitHub: `source = "git@github.com:my-org/fast-modules.git//$1?ref=v1.0"` + - modules stored on Gitlab: `source = "git::ssh://git@gitlab.com/my-org/fast-modules.git//$1?ref=v1.0"` + - modules stored on Source Repositories: `source = git::https://source.developers.google.com/p/my-project/r/my-repository//$1?ref=v1.0"`. You may need to run `git config --global credential.'https://source.developers.google.com'.helper gcloud.sh` first as documented [here](https://cloud.google.com/source-repositories/docs/adding-repositories-as-remotes#add_the_repository_as_a_remote) - copy the generated workflow file for the stage from the GCS output files bucket or from the local clone if enabled - for GitHub, place it in a `.github/workflows` folder in the repository root - for Gitlab, rename it to `.gitlab-ci.yml` and place it in the repository root diff --git a/fast/stages/0-bootstrap/terraform.tfvars.sample b/fast/stages/0-bootstrap/terraform.tfvars.sample index 66710ba4a6..a134f8dc5d 100644 --- a/fast/stages/0-bootstrap/terraform.tfvars.sample +++ b/fast/stages/0-bootstrap/terraform.tfvars.sample @@ -1,15 +1,14 @@ # use `gcloud beta billing accounts list` # if you have too many accounts, check the Cloud Console :) billing_account = { - id = "012345-67890A-BCDEF0" - organization_id = 1234567890 + id = "012345-67890A-BCDEF0" } # use `gcloud organizations list` organization = { - domain = "example.org" - id = 1234567890 - customer_id = "C000001" + domain = "example.org" + id = 1234567890 + customer_id = "C000001" } outputs_location = "~/fast-config" diff --git a/fast/stages/1-resman/README.md b/fast/stages/1-resman/README.md index c2091eb50a..971c69633d 100644 --- a/fast/stages/1-resman/README.md +++ b/fast/stages/1-resman/README.md @@ -13,6 +13,22 @@ The following diagram is a high level reference of the resources created and man Resource-management diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [Multitenancy](#multitenancy) + - [Workload Identity Federation and CI/CD](#workload-identity-federation-and-cicd) +- [How to run this stage](#how-to-run-this-stage) + - [Provider and Terraform variables](#provider-and-terraform-variables) + - [Impersonating the automation service account](#impersonating-the-automation-service-account) + - [Variable configuration](#variable-configuration) + - [Running the stage](#running-the-stage) +- [Customizations](#customizations) + - [Team folders](#team-folders) + - [Organization Policies](#organization-policies) + - [IAM](#iam) + - [Additional folders](#additional-folders) + ## Design overview and choices Despite its simplicity, this stage implements the basics of a design that we've seen working well for a variety of customers, where the hierarchy is laid out following two conceptually different approaches: @@ -54,51 +70,49 @@ It's of course possible to run this stage in isolation, but that's outside the s Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -### Providers configuration - -The default way of making sure you have the right permissions, is to use the identity of the service account pre-created for this stage during bootstrap, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). +### Provider and Terraform variables -To simplify setup, the previous stage pre-configures a valid providers file in its output, and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. -If you have set a valid value for `outputs_location` in the bootstrap stage (see the [bootstrap stage README](../0-bootstrap/#output-files-and-cross-stage-variables) for more details), simply link the relevant `providers.tf` file from this stage's folder in the path you specified: +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. ```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/providers/01-resman-providers.tf . -``` +../../stage-links.sh ~/fast-config -If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage's outputs: +# copy and paste the following commands for '1-resman' -```bash -cd ../0-bootstrap -terraform output -json providers | jq -r '.["01-resman"]' \ - > ../1-resman/providers.tf +ln -s ~/fast-config/providers/1-resman-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ ``` -If you want to continue to rely on `outputs_location` logic, create a `terraform.tfvars` file and configure it as described [here](../0-bootstrap/#output-files-and-cross-stage-variables). +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 -### Variable configuration +# copy and paste the following commands for '1-resman' -There are two broad sets of variables you will need to fill in: +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/1-resman-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +``` -- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage +### Impersonating the automation service account -To avoid the tedious job of filling in the first group of variable with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. -If you configured a valid path for `outputs_location` in the bootstrap stage, simply link the relevant `*.auto.tfvars.json` files from the outputs folder. For this stage, you need the `globals.auto.tfvars.json` file containing global values compiled manually for the bootstrap stage, and `0-bootstrap.auto.tfvars.json` containing values derived from resources managed by the bootstrap stage: +### Variable configuration -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json . -``` +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: + +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `0-bootstrap.auto.tfvars.json` file linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file -A second set of variables is specific to this stage, they are all optional so if you need to customize them, create an extra `terraform.tfvars` file. +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. -Refer to the [Variables](#variables) table at the bottom of this document, for a full list of variables, their origin (e.g. a stage or specific to this one), and descriptions explaining their meaning. The sections below also describe some of the possible customizations. For billing configurations, refer to the [Bootstrap documentation on billing](../0-bootstrap/README.md#billing-account) as the `billing_account` variable is identical across all stages. +### Running the stage -Once done, you can run this stage: +Once provider and variable values are in place and the correct user is configured, the stage can be run: ```bash terraform init @@ -139,9 +153,9 @@ This allows to centralize the minimum set of resources to delegate control of ea ### Organization policies -Organization policies are laid out in an explicit manner in the `organization.tf` file, so it's fairly easy to add or remove specific policies. +Organization policies leverage -- with one exception -- the built-in factory implemented in the organization module, and configured via the yaml files in the `data` folder. To edit organization policies, check and edit the files there. -For policies where additional data is needed, a root-level `organization_policy_configs` variable allows passing in specific data. Its built-in use to add additional organizations to the [Domain Restricted Sharing](https://cloud.google.com/resource-manager/docs/organization-policy/restricting-domains) policy, can be taken as an example on how to leverage it for additional customizations. +The one exception is [Domain Restricted Sharing](https://cloud.google.com/resource-manager/docs/organization-policy/restricting-domains), which is made dynamic and implemented in code so as to auto-add the current organization's customer id. The `organization_policy_configs` variable allow to easily add ids from third party organizations if needed. ### IAM diff --git a/fast/stages/1-resman/branch-sandbox.tf b/fast/stages/1-resman/branch-sandbox.tf index 8b54e749a9..72221bc0d1 100644 --- a/fast/stages/1-resman/branch-sandbox.tf +++ b/fast/stages/1-resman/branch-sandbox.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -33,8 +33,8 @@ module "branch-sandbox-folder" { "roles/resourcemanager.projectCreator" = [module.branch-sandbox-sa.0.iam_email] } org_policies = { - "constraints/sql.restrictPublicIp" = { enforce = false } - "constraints/compute.vmExternalIpAccess" = { allow = { all = true } } + "sql.restrictPublicIp" = { rules = [{ enforce = false }] } + "compute.vmExternalIpAccess" = { rules = [{ allow = { all = true } }] } } tag_bindings = { context = try( diff --git a/fast/stages/1-resman/data/org-policies/compute.yaml b/fast/stages/1-resman/data/org-policies/compute.yaml index 0d27ac426d..a3f96b1b1c 100644 --- a/fast/stages/1-resman/data/org-policies/compute.yaml +++ b/fast/stages/1-resman/data/org-policies/compute.yaml @@ -3,71 +3,90 @@ # sample subset of useful organization policies, edit to suit requirements compute.disableGuestAttributesAccess: - enforce: true + rules: + - enforce: true compute.requireOsLogin: - enforce: true + rules: + - enforce: true compute.restrictLoadBalancerCreationForTypes: - allow: - values: - - in:INTERNAL + rules: + - allow: + values: + - in:INTERNAL compute.skipDefaultNetworkCreation: - enforce: true + rules: + - enforce: true compute.vmExternalIpAccess: - deny: - all: true + rules: + - deny: + all: true # compute.disableInternetNetworkEndpointGroup: -# enforce: true +# rules: +# - enforce: true # compute.disableNestedVirtualization: -# enforce: true +# rules: +# - enforce: true # compute.disableSerialPortAccess: -# enforce: true +# rules: +# - enforce: true # compute.restrictCloudNATUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictDedicatedInterconnectUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictPartnerInterconnectUsage: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictProtocolForwardingCreationForTypes: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictSharedVpcHostProjects: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictSharedVpcSubnetworks: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictVpcPeering: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictVpnPeerIPs: -# deny: -# all: true +# rules: +# - deny: +# all: true # compute.restrictXpnProjectLienRemoval: -# enforce: true +# rules: +# - enforce: true # compute.setNewProjectDefaultToZonalDNSOnly: -# enforce: true +# rules: +# - enforce: true # compute.vmCanIpForward: -# deny: -# all: true +# rules: +# - deny: +# all: true diff --git a/fast/stages/1-resman/data/org-policies/iam.yaml b/fast/stages/1-resman/data/org-policies/iam.yaml index 4d83f827fe..58e0032cb3 100644 --- a/fast/stages/1-resman/data/org-policies/iam.yaml +++ b/fast/stages/1-resman/data/org-policies/iam.yaml @@ -3,10 +3,13 @@ # sample subset of useful organization policies, edit to suit requirements iam.automaticIamGrantsForDefaultServiceAccounts: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyCreation: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyUpload: - enforce: true + rules: + - enforce: true diff --git a/fast/stages/1-resman/data/org-policies/serverless.yaml b/fast/stages/1-resman/data/org-policies/serverless.yaml index de62e6c702..3efb23cdee 100644 --- a/fast/stages/1-resman/data/org-policies/serverless.yaml +++ b/fast/stages/1-resman/data/org-policies/serverless.yaml @@ -3,24 +3,29 @@ # sample subset of useful organization policies, edit to suit requirements run.allowedIngress: - allow: - values: - - is:internal + rules: + - allow: + values: + - is:internal # run.allowedVPCEgress: -# allow: -# values: +# rules: +# - allow: +# values: # - is:private-ranges-only # cloudfunctions.allowedIngressSettings: -# allow: -# values: -# - is:ALLOW_INTERNAL_ONLY +# rules: +# - allow: +# values: +# - is:ALLOW_INTERNAL_ONLY # cloudfunctions.allowedVpcConnectorEgressSettings: -# allow: -# values: -# - is:PRIVATE_RANGES_ONLY +# rules: +# - allow: +# values: +# - is:PRIVATE_RANGES_ONLY # cloudfunctions.requireVPCConnector: -# enforce: true +# rules: +# - enforce: true diff --git a/fast/stages/1-resman/data/org-policies/sql.yaml b/fast/stages/1-resman/data/org-policies/sql.yaml index 88b84d9d50..0eee80453a 100644 --- a/fast/stages/1-resman/data/org-policies/sql.yaml +++ b/fast/stages/1-resman/data/org-policies/sql.yaml @@ -3,7 +3,9 @@ # sample subset of useful organization policies, edit to suit requirements sql.restrictAuthorizedNetworks: - enforce: true + rules: + - enforce: true sql.restrictPublicIp: - enforce: true + rules: + - enforce: true diff --git a/fast/stages/1-resman/data/org-policies/storage.yaml b/fast/stages/1-resman/data/org-policies/storage.yaml index 6c0a673f3a..448357b8bc 100644 --- a/fast/stages/1-resman/data/org-policies/storage.yaml +++ b/fast/stages/1-resman/data/org-policies/storage.yaml @@ -3,4 +3,5 @@ # sample subset of useful organization policies, edit to suit requirements storage.uniformBucketLevelAccess: - enforce: true + rules: + - enforce: true diff --git a/fast/stages/1-resman/organization.tf b/fast/stages/1-resman/organization.tf index 3d7db46dbc..a3bc2f0de0 100644 --- a/fast/stages/1-resman/organization.tf +++ b/fast/stages/1-resman/organization.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -68,7 +68,11 @@ module "organization" { # sample subset of useful organization policies, edit to suit requirements org_policies = { - "iam.allowedPolicyMemberDomains" = { allow = { values = local.all_drs_domains } } + "iam.allowedPolicyMemberDomains" = { + rules = [ + { allow = { values = local.all_drs_domains } } + ] + } #"gcp.resourceLocations" = { # allow = { values = local.allowed_regions } diff --git a/fast/stages/2-networking-a-peering/README.md b/fast/stages/2-networking-a-peering/README.md index 7966ce80bb..c066423cdd 100644 --- a/fast/stages/2-networking-a-peering/README.md +++ b/fast/stages/2-networking-a-peering/README.md @@ -15,6 +15,33 @@ The following diagram illustrates the high-level design, and should be used as a Networking diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [VPC design](#vpc-design) + - [External connectivity](#external-connectivity) + - [Internal connectivity](#internal-connectivity) + - [IP ranges, subnetting, routing](#ip-ranges-subnetting-routing) + - [Internet egress](#internet-egress) + - [VPC and Hierarchical Firewall](#vpc-and-hierarchical-firewall) + - [DNS](#dns) +- [Stage structure and files layout](#stage-structure-and-files-layout) + - [VPCs](#vpcs) + - [VPNs](#vpns) + - [Routing and BGP](#routing-and-bgp) + - [Firewall](#firewall) + - [DNS architecture](#dns-architecture) + - [Private Google Access](#private-google-access) +- [How to run this stage](#how-to-run-this-stage) + - [Provider and Terraform variables](#provider-and-terraform-variables) + - [Impersonating the automation service account](#impersonating-the-automation-service-account) + - [Variable configuration](#variable-configuration) + - [Running the stage](#running-the-stage) + - [Post-deployment activities](#post-deployment-activities) +- [Customizations](#customizations) + - [Changing default regions](#changing-default-regions) + - [Adding an environment](#adding-an-environment) + ## Design overview and choices ### VPC design @@ -44,13 +71,13 @@ As mentioned initially, there are of course other ways to implement internal con This is a summary of the main options: -- [HA VPN](https://cloud.google.com/network-connectivity/docs/vpn/concepts/topologies) (implemented by [02-networking-vpn](../2-networking-b-vpn/)) +- [HA VPN](https://cloud.google.com/network-connectivity/docs/vpn/concepts/topologies) (implemented by [2-networking-vpn](../2-networking-b-vpn/)) - Pros: simple compatibility with GCP services that leverage peering internally, better control on routes, avoids peering groups shared quotas and limits - Cons: additional cost, marginal increase in latency, requires multiple tunnels for full bandwidth - [VPC Peering](https://cloud.google.com/vpc/docs/vpc-peering) (implemented here) - Pros: no additional costs, full bandwidth with no configurations, no extra latency, total environment isolation - Cons: no transitivity (e.g. to GKE masters, Cloud SQL, etc.), no selective exchange of routes, several quotas and limits shared between VPCs in a peering group -- [Multi-NIC appliances](https://cloud.google.com/architecture/best-practices-vpc-design#multi-nic) (implemented by [02-networking-nva](../2-networking-c-nva/)) +- [Multi-NIC appliances](https://cloud.google.com/architecture/best-practices-vpc-design#multi-nic) (implemented by [2-networking-nva](../2-networking-c-nva/)) - Pros: additional security features (e.g. IPS), potentially better integration with on-prem systems by using the same vendor - Cons: complex HA/failover setup, limited by VM bandwidth and scale, additional costs for VMs and licenses, out of band management of a critical cloud component @@ -120,58 +147,7 @@ From cloud, the `example.com` domain (used as a placeholder) is forwarded to on- This configuration is battle-tested, and flexible enough to lend itself to simple modifications without subverting its design, for example by forwarding and peering root zones to bypass Cloud DNS external resolution. -## How to run this stage - -This stage is meant to be executed after the [resman](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. - -It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. - -Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. - -### Providers configuration - -The default way of making sure you have the right permissions, is to use the identity of the service account pre-created for this stage during the [resource management](../1-resman) stage, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). - -To simplify setup, the previous stage pre-configures a valid providers file in its output, and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. - -If you have set a valid value for `outputs_location` in the bootstrap stage, simply link the relevant `providers.tf` file from this stage's folder in the path you specified: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/providers/02-networking-providers.tf . -``` - -If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage's outputs: - -```bash -cd ../1-resman -terraform output -json providers | jq -r '.["02-networking"]' \ - > ../02-networking/providers.tf -``` - -### Variable configuration - -There are two broad sets of variables you will need to fill in: - -- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage - -To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. - -If you have set a valid value for `outputs_location` in the bootstrap and in the resman stage, simply link the relevant `*.auto.tfvars.json` files from this stage's folder in the path you specified. -The `*` above is set to the name of the stage that produced it, except for `globals.auto.tfvars.json` which is also generated by the bootstrap stage, containing global values compiled manually for the bootstrap stage. -For this stage, link the following files: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -ln -s ~/fast-config/tfvars/00-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/01-resman.auto.tfvars.json . -``` - -A second set of variables is specific to this stage, they are all optional so if you need to customize them, create an extra `terraform.tfvars` file. - -Please refer to the [Variables](#variables) table below for a map of the variable origins, and to the sections below on how to adapt this stage to your networking configuration. +## Stage structure and files layout ### VPCs @@ -224,27 +200,64 @@ DNS queries sent to the on-premises infrastructure come from the `35.199.192.0/1 The [Inbound DNS Policy](https://cloud.google.com/dns/docs/server-policies-overview#dns-server-policy-in) defined in module `landing-vpc` ([`landing.tf`](./landing.tf)) automatically reserves the first available IP address on each created subnet (typically the third one in a CIDR) to expose the Cloud DNS service so that it can be consumed from outside of GCP. -### Private Google Access +## How to run this stage -[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. +This stage is meant to be executed after the [resource management](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. -For PGA to work: +It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. -- Private Google Access should be enabled on the subnet. \ -Subnets created by the `net-vpc` module are PGA-enabled by default. +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ -Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC (e.g. see `landing-vpc` in [`landing.tf`](./landing.tf)) has explicit routes set in case the `0.0.0.0/0` route is changed. +### Provider and Terraform variables -- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in [`dns-landing.tf`](./dns-landing.tf) +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. + +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. + +```bash +../../stage-links.sh ~/fast-config -### Preliminar activities +# copy and paste the following commands for '2-networking-a-peering' -Before running `terraform apply` on this stage, make sure to adapt all of `variables.tf` to your needs, to update all reference to regions (e.g. `europe-west1` or `ew1`) in the whole directory to match your preferences. +ln -s ~/fast-config/providers/2-networking-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ +``` + +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 -If you're not using FAST, you'll also need to create a `providers.tf` file to configure the GCS backend and the service account to use to run the deployment. +# copy and paste the following commands for '2-networking-a-peering' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/2-networking-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +``` -You're now ready to run `terraform init` and `apply`. +### Impersonating the automation service account + +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. + +### Variable configuration + +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: + +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `0-bootstrap.auto.tfvars.json` and `1-resman.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file + +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. + +### Running the stage + +Once provider and variable values are in place and the correct user is configured, the stage can be run: + +```bash +terraform init +terraform apply +``` ### Post-deployment activities @@ -252,8 +265,29 @@ You're now ready to run `terraform init` and `apply`. - On-prem routers should accept BGP sessions from their cloud peers. - On-prem DNS servers should have forward zones for GCP-managed ones. +#### Private Google Access + +[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. + +For PGA to work: + +- Private Google Access should be enabled on the subnet. \ +Subnets created by the `net-vpc` module are PGA-enabled by default. + +- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ +Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC (e.g. see `landing-vpc` in [`landing.tf`](./landing.tf)) has explicit routes set in case the `0.0.0.0/0` route is changed. + +- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in [`dns-landing.tf`](./dns-landing.tf) + ## Customizations +### Changing default regions + +Regions are defined via the `regions` variable which sets up a mapping between the `regions.primary` and `regions.secondary` logical names and actual GCP region names. If you need to change regions from the defaults: + +- change the values of the mappings in the `regions` variable to the regions you are going to use +- change the regions in the factory subnet files in the `data` folder + ### Adding an environment To create a new environment (e.g. `staging`), a few changes are required. @@ -262,10 +296,10 @@ Create a `spoke-staging.tf` file by copying `spoke-prod.tf` file, and adapt the new file by replacing the value "prod" with the value "staging". Running `diff spoke-dev.tf spoke-prod.tf` can help to see how environment files differ. -The new VPC requires a set of dedicated CIDRs, one per region, added to variable `custom_adv` (for example as `spoke_staging_ew1` and `spoke_staging_ew4`). +The new VPC requires a set of dedicated CIDRs, one per region, added to variable `custom_adv` (for example as `spoke_staging_primary` and `spoke_staging_secondary`). >`custom_adv` is a map that "resolves" CIDR names to actual addresses, and will be used later to configure routing. > -Variables managing L7 Interal Load Balancers (`l7ilb_subnets`) and Private Service Access (`psa_ranges`) should also be adapted, and subnets and firewall rules for the new spoke should be added as described above. +Variables managing L7 Internal Load Balancers (`l7ilb_subnets`) and Private Service Access (`psa_ranges`) should also be adapted, and subnets and firewall rules for the new spoke should be added as described above. DNS configurations are centralised in the `dns-*.tf` files. Spokes delegate DNS resolution to Landing through DNS peering, and optionally define a private zone (e.g. `dev.gcp.example.com`) which the landing peers to. To configure DNS for a new environment, copy one of the other environments DNS files [e.g. (dns-dev.tf](dns-dev.tf)) into a new `dns-*.tf` file suffixed with the environment name (e.g. `dns-staging.tf`), and update its content accordingly. Don't forget to add a peering zone from the landing to the newly created environment private zone. diff --git a/fast/stages/2-networking-a-peering/vpn-onprem.tf b/fast/stages/2-networking-a-peering/vpn-onprem.tf index a04a009765..2e9f3c24c9 100644 --- a/fast/stages/2-networking-a-peering/vpn-onprem.tf +++ b/fast/stages/2-networking-a-peering/vpn-onprem.tf @@ -48,8 +48,10 @@ module "landing-to-onprem-primary-vpn" { name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_onprem_configs.landing-primary.asn } - peer_gateway = { - external = var.vpn_onprem_configs.landing-primary.peer_external_gateway + peer_gateways = { + default = { + external = var.vpn_onprem_configs.landing-primary.peer_external_gateway + } } tunnels = { for t in var.vpn_onprem_configs.landing-primary.tunnels : diff --git a/fast/stages/2-networking-b-vpn/README.md b/fast/stages/2-networking-b-vpn/README.md index 2177f3113b..7a8983d81b 100644 --- a/fast/stages/2-networking-b-vpn/README.md +++ b/fast/stages/2-networking-b-vpn/README.md @@ -15,6 +15,33 @@ The following diagram illustrates the high-level design, and should be used as a Networking diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [VPC design](#vpc-design) + - [External connectivity](#external-connectivity) + - [Internal connectivity](#internal-connectivity) + - [IP ranges, subnetting, routing](#ip-ranges-subnetting-routing) + - [Internet egress](#internet-egress) + - [VPC and Hierarchical Firewall](#vpc-and-hierarchical-firewall) + - [DNS](#dns) +- [Stage structure and files layout](#stage-structure-and-files-layout) + - [VPCs](#vpcs) + - [VPNs](#vpns) + - [Routing and BGP](#routing-and-bgp) + - [Firewall](#firewall) + - [DNS architecture](#dns-architecture) + - [Private Google Access](#private-google-access) +- [How to run this stage](#how-to-run-this-stage) + - [Provider and Terraform variables](#provider-and-terraform-variables) + - [Impersonating the automation service account](#impersonating-the-automation-service-account) + - [Variable configuration](#variable-configuration) + - [Running the stage](#running-the-stage) + - [Post-deployment activities](#post-deployment-activities) +- [Customizations](#customizations) + - [Changing default regions](#changing-default-regions) + - [Adding an environment](#adding-an-environment) + ## Design overview and choices ### VPC design @@ -45,10 +72,10 @@ This is a summary of the main options: - [HA VPN](https://cloud.google.com/network-connectivity/docs/vpn/concepts/topologies) (implemented here) - Pros: simple compatibility with GCP services that leverage peering internally, better control on routes, avoids peering groups shared quotas and limits - Cons: additional cost, marginal increase in latency, requires multiple tunnels for full bandwidth -- [VPC Peering](https://cloud.google.com/vpc/docs/vpc-peering) (implemented by [02-networking-peering](../2-networking-a-peering/)) +- [VPC Peering](https://cloud.google.com/vpc/docs/vpc-peering) (implemented by [2-networking-peering](../2-networking-a-peering/)) - Pros: no additional costs, full bandwidth with no configurations, no extra latency - Cons: no transitivity (e.g. to GKE masters, Cloud SQL, etc.), no selective exchange of routes, several quotas and limits shared between VPCs in a peering group -- [Multi-NIC appliances](https://cloud.google.com/architecture/best-practices-vpc-design#multi-nic) (implemented by [02-networking-nva](../2-networking-c-nva/)) +- [Multi-NIC appliances](https://cloud.google.com/architecture/best-practices-vpc-design#multi-nic) (implemented by [2-networking-nva](../2-networking-c-nva/)) - Pros: additional security features (e.g. IPS), potentially better integration with on-prem systems by using the same vendor - Cons: complex HA/failover setup, limited by VM bandwidth and scale, additional costs for VMs and licenses, out of band management of a critical cloud component @@ -126,58 +153,7 @@ From cloud, the `example.com` domain (used as a placeholder) is forwarded to on- This configuration is battle-tested, and flexible enough to lend itself to simple modifications without subverting its design, for example by forwarding and peering root zones to bypass Cloud DNS external resolution. -## How to run this stage - -This stage is meant to be executed after the [resman](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. - -It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. - -Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. - -### Providers configuration - -The default way of making sure you have the right permissions, is to use the identity of the service account pre-created for this stage during the [resource management](../1-resman) stage, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). - -To simplify setup, the previous stage pre-configures a valid providers file in its output, and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. - -If you have set a valid value for `outputs_location` in the bootstrap stage, simply link the relevant `providers.tf` file from this stage's folder in the path you specified: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/providers/02-networking-providers.tf . -``` - -If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage's outputs: - -```bash -cd ../1-resman -terraform output -json providers | jq -r '.["02-networking"]' \ - > ../02-networking/providers.tf -``` - -### Variable configuration - -There are two broad sets of variables you will need to fill in: - -- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage - -To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. - -If you have set a valid value for `outputs_location` in the bootstrap and in the resman stage, simply link the relevant `*.auto.tfvars.json` files from this stage's folder in the path you specified. -The `*` above is set to the name of the stage that produced it, except for `globals.auto.tfvars.json` which is also generated by the bootstrap stage, containing global values compiled manually for the bootstrap stage. -For this stage, link the following files: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -ln -s ~/fast-config/tfvars/00-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/01-resman.auto.tfvars.json . -``` - -A second set of variables is specific to this stage, they are all optional so if you need to customize them, create an extra `terraform.tfvars` file. - -Please refer to the [Variables](#variables) table below for a map of the variable origins, and to the sections below on how to adapt this stage to your networking configuration. +## Stage structure and files layout ### VPCs @@ -238,27 +214,64 @@ DNS queries sent to the on-premises infrastructure come from the `35.199.192.0/1 The [Inbound DNS Policy](https://cloud.google.com/dns/docs/server-policies-overview#dns-server-policy-in) defined in module `landing-vpc` ([`landing.tf`](./landing.tf)) automatically reserves the first available IP address on each created subnet (typically the third one in a CIDR) to expose the Cloud DNS service so that it can be consumed from outside of GCP. -### Private Google Access +## How to run this stage -[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. +This stage is meant to be executed after the [resource management](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. -For PGA to work: +It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. -- Private Google Access should be enabled on the subnet. \ -Subnets created by the `net-vpc` module are PGA-enabled by default. +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ -Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC (e.g. see `landing-vpc` in [`landing.tf`](./landing.tf)) has explicit routes set in case the `0.0.0.0/0` route is changed. +### Provider and Terraform variables + +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. + +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. + +```bash +../../stage-links.sh ~/fast-config + +# copy and paste the following commands for '2-networking-a-peering' + +ln -s ~/fast-config/providers/2-networking-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ +``` + +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '2-networking-a-peering' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/2-networking-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +``` + +### Impersonating the automation service account + +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. + +### Variable configuration -- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in [dns-landing.tf](./dns-landing.tf) +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: -### Preliminary activities +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `0-bootstrap.auto.tfvars.json` and `1-resman.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file -Before running `terraform apply` on this stage, make sure to adapt all of `variables.tf` and `vpn-variables.tf` to your needs, to update all references to regions (e.g. `europe-west1` or `ew1`) in the whole directory to match your preferences. +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. -If you're not using FAST, you'll also need to create a `providers.tf` file to configure the GCS backend and the service account to use to run the deployment. +### Running the stage -You're now ready to run `terraform init` and `apply`. +Once provider and variable values are in place and the correct user is configured, the stage can be run: + +```bash +terraform init +terraform apply +``` ### Post-deployment activities @@ -266,8 +279,29 @@ You're now ready to run `terraform init` and `apply`. - On-prem routers should accept BGP sessions from their cloud peers. - On-prem DNS servers should have forward zones for GCP-managed ones. +#### Private Google Access + +[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. + +For PGA to work: + +- Private Google Access should be enabled on the subnet. \ +Subnets created by the `net-vpc` module are PGA-enabled by default. + +- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ +Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC (e.g. see `landing-vpc` in [`landing.tf`](./landing.tf)) has explicit routes set in case the `0.0.0.0/0` route is changed. + +- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in [`dns-landing.tf`](./dns-landing.tf) + ## Customizations +### Changing default regions + +Regions are defined via the `regions` variable which sets up a mapping between the `regions.primary` and `regions.secondary` logical names and actual GCP region names. If you need to change regions from the defaults: + +- change the values of the mappings in the `regions` variable to the regions you are going to use +- change the regions in the factory subnet files in the `data` folder + ### Adding an environment To create a new environment (e.g. `staging`), a few changes are required. diff --git a/fast/stages/2-networking-b-vpn/vpn-onprem.tf b/fast/stages/2-networking-b-vpn/vpn-onprem.tf index a04a009765..2e9f3c24c9 100644 --- a/fast/stages/2-networking-b-vpn/vpn-onprem.tf +++ b/fast/stages/2-networking-b-vpn/vpn-onprem.tf @@ -48,8 +48,10 @@ module "landing-to-onprem-primary-vpn" { name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_onprem_configs.landing-primary.asn } - peer_gateway = { - external = var.vpn_onprem_configs.landing-primary.peer_external_gateway + peer_gateways = { + default = { + external = var.vpn_onprem_configs.landing-primary.peer_external_gateway + } } tunnels = { for t in var.vpn_onprem_configs.landing-primary.tunnels : diff --git a/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf b/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf index 09cc31e03e..97adc642fa 100644 --- a/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf +++ b/fast/stages/2-networking-b-vpn/vpn-spoke-dev.tf @@ -50,7 +50,9 @@ module "landing-to-dev-primary-vpn" { name = "landing-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_spoke_configs.landing-primary.asn } - peer_gateway = { gcp = module.dev-to-landing-primary-vpn.self_link } + peer_gateways = { + default = { gcp = module.dev-to-landing-primary-vpn.self_link } + } tunnels = { 0 = { bgp_peer = { @@ -95,7 +97,9 @@ module "dev-to-landing-primary-vpn" { name = "dev-spoke-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_spoke_configs.spoke-dev-primary.asn } - peer_gateway = { gcp = module.landing-to-dev-primary-vpn.self_link } + peer_gateways = { + default = { gcp = module.landing-to-dev-primary-vpn.self_link } + } tunnels = { 0 = { bgp_peer = { diff --git a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf index 071b1d0545..9d36c16e50 100644 --- a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf +++ b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-primary.tf @@ -33,7 +33,9 @@ module "landing-to-prod-primary-vpn" { name = "landing-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_spoke_configs.landing-primary.asn } - peer_gateway = { gcp = module.prod-to-landing-primary-vpn.self_link } + peer_gateways = { + default = { gcp = module.prod-to-landing-primary-vpn.self_link } + } tunnels = { 0 = { bgp_peer = { @@ -75,7 +77,9 @@ module "prod-to-landing-primary-vpn" { name = "prod-spoke-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_spoke_configs.spoke-prod-primary.asn } - peer_gateway = { gcp = module.landing-to-prod-primary-vpn.self_link } + peer_gateways = { + default = { gcp = module.landing-to-prod-primary-vpn.self_link } + } tunnels = { 0 = { bgp_peer = { diff --git a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf index a7c0e0fe18..a3ee9e9fc6 100644 --- a/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf +++ b/fast/stages/2-networking-b-vpn/vpn-spoke-prod-secondary.tf @@ -33,7 +33,9 @@ module "landing-to-prod-secondary-vpn" { name = "landing-vpn-${local.region_shortnames[var.regions.secondary]}" asn = var.router_spoke_configs.landing-secondary.asn } - peer_gateway = { gcp = module.prod-to-landing-secondary-vpn.self_link } + peer_gateways = { + default = { gcp = module.prod-to-landing-secondary-vpn.self_link } + } tunnels = { 0 = { bgp_peer = { @@ -75,7 +77,9 @@ module "prod-to-landing-secondary-vpn" { name = "prod-spoke-vpn-${local.region_shortnames[var.regions.secondary]}" asn = var.router_spoke_configs.spoke-prod-secondary.asn } - peer_gateway = { gcp = module.landing-to-prod-secondary-vpn.self_link } + peer_gateways = { + default = { gcp = module.landing-to-prod-secondary-vpn.self_link } + } tunnels = { 0 = { bgp_peer = { diff --git a/fast/stages/2-networking-c-nva/README.md b/fast/stages/2-networking-c-nva/README.md index 425e1d195e..d0e62fd62a 100644 --- a/fast/stages/2-networking-c-nva/README.md +++ b/fast/stages/2-networking-c-nva/README.md @@ -21,6 +21,34 @@ The final number of subnets, and their IP addressing will depend on the user-spe Networking diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [Multi-regional deployment](#multi-regional-deployment) + - [VPC design](#vpc-design) + - [External connectivity](#external-connectivity) + - [Internal connectivity](#internal-connectivity) + - [IP ranges, subnetting, routing](#ip-ranges-subnetting-routing) + - [Internet egress](#internet-egress) + - [VPC and Hierarchical Firewall](#vpc-and-hierarchical-firewall) + - [DNS](#dns) +- [Stage structure and files layout](#stage-structure-and-files-layout) + - [VPCs](#vpcs) + - [VPNs](#vpns) + - [Routing and BGP](#routing-and-bgp) + - [Firewall](#firewall) + - [DNS architecture](#dns-architecture) + - [Private Google Access](#private-google-access) +- [How to run this stage](#how-to-run-this-stage) + - [Provider and Terraform variables](#provider-and-terraform-variables) + - [Impersonating the automation service account](#impersonating-the-automation-service-account) + - [Variable configuration](#variable-configuration) + - [Running the stage](#running-the-stage) + - [Post-deployment activities](#post-deployment-activities) +- [Customizations](#customizations) + - [Changing default regions](#changing-default-regions) + - [Adding an environment](#adding-an-environment) + ## Design overview and choices ### Multi-regional deployment @@ -190,58 +218,7 @@ In GCP, a forwarding zone in the landing project is configured to forward querie This configuration is battle-tested, and flexible enough to lend itself to simple modifications without subverting its design. -## How to run this stage - -This stage is meant to be executed after the [resman](../1-resman) stage has run. It leverages the automation service account and the storage bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. - -It's possible to run this stage in isolation, but that's outside of the scope of this document. Please, refer to the previous stages for the environment requirements. - -Before running this stage, you need to make sure you have the correct credentials and permissions. You'll also need identify the module variables and make sure you assign them the values that match your configuration. - -### Providers configuration - -The default way of making sure you have the right permissions, is to use the identity of the service account pre-created for this stage, during the [resource management](../1-resman) stage, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). - -To simplify the setup, the previous stage pre-configures a valid providers file in its output and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. - -If you have set a valid value for `outputs_location` in the bootstrap stage, simply link the relevant `providers.tf` file from this stage folder in the path you selected: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/providers/02-networking-providers.tf . -``` - -If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage outputs: - -```bash -cd ../1-resman -terraform output -json providers | jq -r '.["02-networking"]' \ - > ../2-networking-c-nva/providers.tf -``` - -### Variable configuration - -There are two broad sets of variables you will need to fill in: - -- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage - -To avoid the tedious job of filling in the first group of variables with values derived from other stages outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. - -If you have set a valid value for `outputs_location` in the bootstrap and in the resman stage, simply link the relevant `*.auto.tfvars.json` files from this stage's folder in the path you specified. -The `*` above is set to the name of the stage that produced it, except for `globals.auto.tfvars.json` which is also generated by the bootstrap stage, containing global values compiled manually for the bootstrap stage. -For this stage, link the following files: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -ln -s ~/fast-config/tfvars/00-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/01-resman.auto.tfvars.json . -``` - -A second set of variables is specific to this stage, they are all optional so if you need to customize them, create an extra `terraform.tfvars` file. - -Please, refer to the [variables](#variables) table below for a map of the variable origins, and use the sections below to understand how to adapt this stage to your networking configuration. +## Stage structure and files layout ### VPCs @@ -286,46 +263,104 @@ Cloud DNS manages onprem forwarding, the main GCP zone (in this example `gcp.exa The root DNS zone defined in the landing project acts as the source of truth for DNS within the Cloud environment. The resources defined in the spoke VPCs consume the landing DNS infrastructure through DNS peering (e.g. `prod-landing-root-dns-peering`). The spokes can optionally define private zones (e.g. `prod-dns-private-zone`). Granting visibility both to the trusted and untrusted landing VPCs ensures that the whole cloud environment can query such zones. -#### Cloud to on-premises +#### Cloud to on-prem Leveraging the forwarding zone defined in the landing project (e.g. `onprem-example-dns-forwarding` and `reverse-10-dns-forwarding`), the cloud environment can resolve `in-addr.arpa.` and `onprem.example.com.` using the on-premise DNS infrastructure. On-premise resolver IPs are set in the variable `dns.onprem`. DNS queries sent to the on-premise infrastructure come from the `35.199.192.0/19` source range. -#### On-premises to cloud +#### On-prem to cloud The [Inbound DNS Policy](https://cloud.google.com/dns/docs/server-policies-overview#dns-server-policy-in) defined in the *trusted landing VPC module* ([`landing.tf`](./landing.tf)) automatically reserves the first available IP address on each subnet (typically the third one in a CIDR) to expose the Cloud DNS service, so that it can be consumed from outside of GCP. -### Private Google Access +## How to run this stage -[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) is configured in this environment. It enables VMs and on-premise systems to consume Google APIs from within the Google network. +This stage is meant to be executed after the [resource management](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. -For PGA to work: +It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. -- Private Google Access should be enabled on the subnet. \ -Subnets created using the `net-vpc` module are PGA-enabled by default. +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-premises to the trusted landing VPC, and from there to the `default-internet-gateway`. \ -The `vpn_onprem_configs` variable contains the ranges advertised from GCP to on-premises. Furthermore, the trusted landing VPC (e.g. see `landing-trusted-vpc` in [`landing.tf`](./landing.tf)) has explicit routes to send traffic destined to restricted and private - googleapis.com to the Internet gateway (which works for Google APIs only, and not for the whole Internet, since Cloud NAT is not configured in the trusted landing VPC). +### Provider and Terraform variables -- On-premises, a private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain). Its configuration can be copied from the module `googleapis-private-zone` in [`dns-landing.tf`](./dns-landing.tf) +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. -### Preliminar activities +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. -Before running `terraform apply`, make sure to adapt `variables.tf` to your needs, to update the variable values using a new `terraform.tfvars` file, and to update the references to the regions in the whole directory, in order to match your preferences (e.g. `europe-west1` or `ew1`). +```bash +../../stage-links.sh ~/fast-config + +# copy and paste the following commands for '2-networking-a-peering' + +ln -s ~/fast-config/providers/2-networking-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ +``` + +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '2-networking-a-peering' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/2-networking-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +``` + +### Impersonating the automation service account + +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. + +### Variable configuration + +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: + +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `0-bootstrap.auto.tfvars.json` and `1-resman.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file -If you're not using other FAST stages, you'll also need to create a `providers.tf` file to configure the GCS backend and the service account to use to run the deployment. +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. -You're now ready to run `terraform init` and `terraform apply`. +### Running the stage + +Once provider and variable values are in place and the correct user is configured, the stage can be run: + +```bash +terraform init +terraform apply +``` ### Post-deployment activities -- On-premise routers should be configured to advertise all relevant CIDRs to the GCP environments. To avoid hitting GCP quotas, we recommend aggregating routes as much as possible -- On-premise routers should accept BGP sessions from their cloud peers -- On-premise DNS servers should have forward zones configured, in order to resolve GCP-managed domains +- On-prem routers should be configured to advertise all relevant CIDRs to the GCP environments. To avoid hitting GCP quotas, we recomment aggregating routes as much as possible. +- On-prem routers should accept BGP sessions from their cloud peers. +- On-prem DNS servers should have forward zones for GCP-managed ones. + +#### Private Google Access + +[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. + +For PGA to work: + +- Private Google Access should be enabled on the subnet. \ +Subnets created by the `net-vpc` module are PGA-enabled by default. + +- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ +Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC (e.g. see `landing-vpc` in [`landing.tf`](./landing.tf)) has explicit routes set in case the `0.0.0.0/0` route is changed. + +- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in [`dns-landing.tf`](./dns-landing.tf) ## Customizations +### Changing default regions + +Regions are defined via the `regions` variable which sets up a mapping between the `regions.primary` and `regions.secondary` logical names and actual GCP region names. If you need to change regions from the defaults: + +- change the values of the mappings in the `regions` variable to the regions you are going to use +- change the regions in the factory subnet files in the `data` folder + ### Adding an environment To create a new environment (e.g. `staging`), a few changes are required: diff --git a/fast/stages/2-networking-c-nva/vpn-onprem.tf b/fast/stages/2-networking-c-nva/vpn-onprem.tf index 57f2024a9a..31adbe71c9 100644 --- a/fast/stages/2-networking-c-nva/vpn-onprem.tf +++ b/fast/stages/2-networking-c-nva/vpn-onprem.tf @@ -51,8 +51,10 @@ module "landing-to-onprem-primary-vpn" { name = "landing-onprem-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_configs.landing-trusted-primary.asn } - peer_gateway = { - external = var.vpn_onprem_configs.landing-trusted-primary.peer_external_gateway + peer_gateways = { + default = { + external = var.vpn_onprem_configs.landing-trusted-primary.peer_external_gateway + } } tunnels = { for t in var.vpn_onprem_configs.landing-trusted-primary.tunnels : @@ -85,8 +87,10 @@ module "landing-to-onprem-secondary-vpn" { name = "landing-onprem-vpn-${local.region_shortnames[var.regions.secondary]}" asn = var.router_configs.landing-trusted-secondary.asn } - peer_gateway = { - external = var.vpn_onprem_configs.landing-trusted-secondary.peer_external_gateway + peer_gateways = { + default = { + external = var.vpn_onprem_configs.landing-trusted-secondary.peer_external_gateway + } } tunnels = { for t in var.vpn_onprem_configs.landing-trusted-secondary.tunnels : diff --git a/fast/stages/2-networking-d-separate-envs/README.md b/fast/stages/2-networking-d-separate-envs/README.md index a461dc97bf..dfc199cd0f 100644 --- a/fast/stages/2-networking-d-separate-envs/README.md +++ b/fast/stages/2-networking-d-separate-envs/README.md @@ -1,4 +1,4 @@ -# Networking +# Networking with separated single environment This stage sets up the shared network infrastructure for the whole organization. It implements a single shared VPC per environment, where each environment is independently connected to the on-premise environment, to maintain a fully separated routing domain on GCP. @@ -14,6 +14,31 @@ The following diagram illustrates the high-level design, and should be used as a Networking diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [VPC design](#vpc-design) + - [External connectivity](#external-connectivity) + - [IP ranges, subnetting, routing](#ip-ranges-subnetting-routing) + - [Internet egress](#internet-egress) + - [VPC and Hierarchical Firewall](#vpc-and-hierarchical-firewall) + - [DNS](#dns) +- [Stage structure and files layout](#stage-structure-and-files-layout) + - [VPCs](#vpcs) + - [VPNs](#vpns) + - [Routing and BGP](#routing-and-bgp) + - [Firewall](#firewall) + - [DNS architecture](#dns-architecture) + - [Private Google Access](#private-google-access) +- [How to run this stage](#how-to-run-this-stage) + - [Provider and Terraform variables](#provider-and-terraform-variables) + - [Impersonating the automation service account](#impersonating-the-automation-service-account) + - [Variable configuration](#variable-configuration) + - [Running the stage](#running-the-stage) + - [Post-deployment activities](#post-deployment-activities) +- [Customizations](#customizations) + - [Changing default regions](#changing-default-regions) + ## Design overview and choices ### VPC design @@ -87,57 +112,7 @@ From cloud, the `example.com` domain (used as a placeholder) is forwarded to on- This configuration is battle-tested, and flexible enough to lend itself to simple modifications without subverting its design, for example by forwarding and peering root zones to bypass Cloud DNS external resolution. -## How to run this stage - -This stage is meant to be executed after the [resman](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. - -It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. - -Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. - -### Providers configuration - -The default way of making sure you have the right permissions, is to use the identity of the service account pre-created for this stage during the [resource management](../1-resman) stage, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). - -To simplify setup, the previous stage pre-configures a valid providers file in its output, and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. - -If you have set a valid value for `outputs_location` in the bootstrap stage, simply link the relevant `providers.tf` file from this stage's folder in the path you specified: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/providers/02-networking-providers.tf . -``` - -If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage's outputs: - -```bash -cd ../1-resman -terraform output -json providers | jq -r '.["02-networking"]' \ - > ../02-networking/providers.tf -``` - -### Variable configuration - -There are two broad sets of variables you will need to fill in: - -- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage - -To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. - -If you have set a valid value for `outputs_location` in the bootstrap and in the resman stage, simply link the relevant `terraform-*.auto.tfvars.json` files from this stage's folder in the path you specified, where the `*` above is set to the name of the stage that produced it. For this stage, a single `.tfvars` file is available: - -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ../../configs/example/02-networking/terraform-bootstrap.auto.tfvars.json -ln -s ../../configs/example/02-networking/terraform-resman.auto.tfvars.json -# also copy the tfvars file used for the bootstrap stage -cp ../0-bootstrap/terraform.tfvars . -``` - -A second set of variables is specific to this stage, they are all optional so if you need to customize them, add them to the file copied from bootstrap. - -Please refer to the [Variables](#variables) table below for a map of the variable origins, and to the sections below on how to adapt this stage to your networking configuration. +## Stage structure and files layout ### VPCs @@ -187,27 +162,64 @@ When implementing this architecture, make sure you'll be able to route packets c The [Inbound DNS Policy](https://cloud.google.com/dns/docs/server-policies-overview#dns-server-policy-in) defined on eachVPC automatically reserves the first available IP address on each created subnet (typically the third one in a CIDR) to expose the Cloud DNS service so that it can be consumed from outside of GCP. -### Private Google Access +## How to run this stage -[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. +This stage is meant to be executed after the [resource management](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. -For PGA to work: +It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. -- Private Google Access should be enabled on the subnet. \ -Subnets created by the `net-vpc` module are PGA-enabled by default. +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ -Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC has explicit routes set in case the `0.0.0.0/0` route is changed. +### Provider and Terraform variables + +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. + +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. + +```bash +../../stage-links.sh ~/fast-config + +# copy and paste the following commands for '2-networking-a-peering' + +ln -s ~/fast-config/providers/2-networking-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ +``` + +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '2-networking-a-peering' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/2-networking-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +``` + +### Impersonating the automation service account + +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. + +### Variable configuration + +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: -- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain), as implemented in module `googleapis-private-zone` in `dns-xxx.tf` +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `0-bootstrap.auto.tfvars.json` and `1-resman.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file -### Preliminar activities +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. -Before running `terraform apply` on this stage, make sure to adapt all of `variables.tf` to your needs, to update all reference to regions (e.g. `europe-west1` or `ew1`) in the whole directory to match your preferences. +### Running the stage -If you're not using FAST, you'll also need to create a `providers.tf` file to configure the GCS backend and the service account to use to run the deployment. +Once provider and variable values are in place and the correct user is configured, the stage can be run: -You're now ready to run `terraform init` and `apply`. +```bash +terraform init +terraform apply +``` ### Post-deployment activities @@ -215,6 +227,29 @@ You're now ready to run `terraform init` and `apply`. - On-prem routers should accept BGP sessions from their cloud peers. - On-prem DNS servers should have forward zones for GCP-managed ones. +#### Private Google Access + +[Private Google Access](https://cloud.google.com/vpc/docs/private-google-access) (or PGA) enables VMs and on-prem systems to consume Google APIs from within the Google network, and is already fully configured on this environment. + +For PGA to work: + +- Private Google Access should be enabled on the subnet. \ +Subnets created by the `net-vpc` module are PGA-enabled by default. + +- 199.36.153.4/30 (`restricted.googleapis.com`) and 199.36.153.8/30 (`private.googleapis.com`) should be routed from on-prem to VPC, and from there to the `default-internet-gateway`. \ +Per variable `vpn_onprem_configs` such ranges are advertised to onprem - furthermore every VPC has explicit routes set in case the `0.0.0.0/0` route is changed. + +- A private DNS zone for `googleapis.com` should be created and configured per [this article](https://cloud.google.com/vpc/docs/configure-private-google-access-hybrid#config-domain) + +## Customizations + +### Changing default regions + +Regions are defined via the `regions` variable which sets up a mapping between the `regions.primary` and `regions.secondary` logical names and actual GCP region names. If you need to change regions from the defaults: + +- change the values of the mappings in the `regions` variable to the regions you are going to use +- change the regions in the factory subnet files in the `data` folder + diff --git a/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf b/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf index e95cd14f96..c5269c4d49 100644 --- a/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf +++ b/fast/stages/2-networking-d-separate-envs/vpn-onprem-dev.tf @@ -48,8 +48,10 @@ module "dev-to-onprem-primary-vpn" { name = "dev-onprem-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_onprem_configs.dev-primary.asn } - peer_gateway = { - external = var.vpn_onprem_configs.dev-primary.peer_external_gateway + peer_gateways = { + default = { + external = var.vpn_onprem_configs.dev-primary.peer_external_gateway + } } tunnels = { for t in var.vpn_onprem_configs.dev-primary.tunnels : diff --git a/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf b/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf index 0793e2744d..760ba4e5e8 100644 --- a/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf +++ b/fast/stages/2-networking-d-separate-envs/vpn-onprem-prod.tf @@ -32,8 +32,10 @@ module "prod-to-onprem-primary-vpn" { name = "prod-onprem-vpn-${local.region_shortnames[var.regions.primary]}" asn = var.router_onprem_configs.prod-primary.asn } - peer_gateway = { - external = var.vpn_onprem_configs.prod-primary.peer_external_gateway + peer_gateways = { + default = { + external = var.vpn_onprem_configs.prod-primary.peer_external_gateway + } } tunnels = { for t in var.vpn_onprem_configs.prod-primary.tunnels : diff --git a/fast/stages/2-security/README.md b/fast/stages/2-security/README.md index a609cd8144..6486cd7418 100644 --- a/fast/stages/2-security/README.md +++ b/fast/stages/2-security/README.md @@ -12,6 +12,24 @@ The following diagram illustrates the high-level design of created resources and Security diagram

+## Table of contents + +- [Design overview and choices](#design-overview-and-choices) + - [Cloud KMS](#cloud-kms) + - [VPC Service Controls](#vpc-service-controls) +- [How to run this stage](#how-to-run-this-stage) + - [Provider and Terraform variables](#provider-and-terraform-variables) + - [Impersonating the automation service account](#impersonating-the-automation-service-account) + - [Variable configuration](#variable-configuration) + - [Running the stage](#running-the-stage) +- [Customizations](#customizations) + - [KMS keys](#kms-keys) + - [VPC Service Controls configuration](#vpc-service-controls-configuration) + - [Dry-run vs. enforced](#dry-run-vs-enforced) + - [Access levels](#access-levels) + - [Ingress and Egress policies](#ingress-and-egress-policies) + - [Perimeters](#perimeters) + ## Design overview and choices Project-level security resources are grouped into two separate projects, one per environment. This setup matches requirements we frequently observe in real life and provides enough separation without needlessly complicating operations. @@ -42,57 +60,57 @@ Some care needs to be taken with project membership in perimeters, which can onl ## How to run this stage -This stage is meant to be executed after the [resource management](../1-resman) stage has run, as it leverages the folder and automation resources created there. The relevant user groups must also exist, but that's one of the requirements for the previous stages too, so if you ran those successfully, you're good to go. - -It's possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the bootstrap stage for the required roles. +This stage is meant to be executed after the [resource management](../1-resman) stage has run, as it leverages the automation service account and bucket created there, and additional resources configured in the [bootstrap](../0-bootstrap) stage. -Before running this stage, you need to ensure you have the correct credentials and permissions, and customize variables by assigning values that match your configuration. +It's of course possible to run this stage in isolation, but that's outside the scope of this document, and you would need to refer to the code for the previous stages for the environmental requirements. -### Providers configuration +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -The default way of making sure you have the correct permissions is to use the identity of the service account pre-created for this stage during bootstrap, and that you are a member of the group that can impersonate it via provider-level configuration (`gcp-devops` or `organization-admins`). +### Provider and Terraform variables -To simplify setup, the previous stage pre-configures a valid providers file in its output, and optionally writes it to a local file if the `outputs_location` variable is set to a valid path. +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. -If you have set a valid value for `outputs_location` in the resource management stage, simply link the relevant `providers.tf` file from this stage's folder in the path you specified: +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. ```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/providers/02-security-providers.tf . -``` +../../stage-links.sh ~/fast-config -If you have not configured `outputs_location` in resource management, you can derive the providers file from that stage's outputs: +# copy and paste the following commands for '2-security' -```bash -cd ../1-resman -terraform output -json providers | jq -r '.["02-security"]' \ - > ../02-security/providers.tf +ln -s ~/fast-config/providers/2-security-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ ``` -### Variable configuration +```bash +../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 -There are two broad sets of variables you will need to fill in: +# copy and paste the following commands for '2-security' -- variables shared by other stages (organization id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/2-security-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +``` -To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. +### Impersonating the automation service account -If you configured a valid path for `outputs_location` in the previous stages, simply link the relevant `terraform-*.auto.tfvars.json` files from this stage's output folder (under the path you specified), where the `*` above is set to the name of the stage that produced it. For this stage, two `.tfvars` files are available: +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. -```bash -# `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/00-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/01-resman.auto.tfvars.json . -# also copy the tfvars file used for the bootstrap stage -cp ../0-bootstrap/terraform.tfvars . -``` +### Variable configuration + +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: + +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `0-bootstrap.auto.tfvars.json` and `1-resman.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file -A second set of optional variables is specific to this stage. If you need to customize them add them to the file copied from bootstrap. +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. -Refer to the [Variables](#variables) table at the bottom of this document, for a full list of variables, their origin (e.g., a stage or specific to this one), and descriptions explaining their meaning. The sections below also describe some of the possible customizations. +### Running the stage -Once done, you can run this stage: +Once provider and variable values are in place and the correct user is configured, the stage can be run: ```bash terraform init diff --git a/fast/stages/3-data-platform/dev/README.md b/fast/stages/3-data-platform/dev/README.md index 615dbde8b0..48d09eafc0 100644 --- a/fast/stages/3-data-platform/dev/README.md +++ b/fast/stages/3-data-platform/dev/README.md @@ -78,74 +78,91 @@ In the case your Data Warehouse need to handle confidential data and you have th ## How to run this stage -This stage can be run in isolation by prviding the necessary variables, but it's really meant to be used as part of the FAST flow after the "foundational stages" ([`00-bootstrap`](../../0-bootstrap), [`01-resman`](../../1-resman), [`02-networking`](../../2-networking-b-vpn) and [`02-security`](../../2-security)). +This stage is meant to be executed after the FAST "foundational" stages: bootstrap, resource management, security and networking stages. -When running in isolation, the following roles are needed on the principal used to apply Terraform: +It's of course possible to run this stage in isolation, refer to the *[Running in isolation](#running-in-isolation)* section below for details. -- on the organization or network folder level - - `roles/xpnAdmin` or a custom role which includes the following permissions - - `"compute.organizations.enableXpnResource"`, - - `"compute.organizations.disableXpnResource"`, - - `"compute.subnetworks.setIamPolicy"`, -- on each folder where projects are created - - `"roles/logging.admin"` - - `"roles/owner"` - - `"roles/resourcemanager.folderAdmin"` - - `"roles/resourcemanager.projectCreator"` -- on the host project for the Shared VPC - - `"roles/browser"` - - `"roles/compute.viewer"` -- on the organization or billing account - - `roles/billing.admin` +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. -The VPC host project, VPC and subnets should already exist. +### Provider and Terraform variables -### Providers configuration +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. -If you're running this on top of Fast, you should run the following commands to create the providers file, and populate the required variables from the previous stage. +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. ```bash -# Variable `outputs_location` is set to `~/fast-config` in stage 01-resman -ln -s ~/fast-config/providers/03-data-platform-dev-providers.tf . -``` +../../../stage-links.sh ~/fast-config -If you have not configured `outputs_location` in bootstrap, you can derive the providers file from that stage's outputs: +# copy and paste the following commands for '3-data-platform' + +ln -s /home/ludomagno/fast-config/providers/3-data-platform-providers.tf ./ +ln -s /home/ludomagno/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/1-resman.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/2-networking.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/2-security.auto.tfvars.json ./ +``` ```bash -cd ../../1-resman -terraform output -json providers | jq -r '.["03-data-platform-dev"]' \ - > ../3-data-platform/dev/providers.tf +../../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '3-data-platform' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/3-data-platform-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-networking.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-security.auto.tfvars.json ./ ``` -### Variable configuration +### Impersonating the automation service account -There are two broad sets of variables that can be configured: +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. -- variables shared by other stages (organization id, billing account id, etc.) or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage +### Variable configuration -To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: -If you configured a valid path for `outputs_location` in the bootstrap security and networking stages, simply link the relevant `terraform-*.auto.tfvars.json` files from this stage's outputs folder under the path you specified. This will also link the providers configuration file: +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `*.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file -```bash -# Variable `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/00-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/01-resman.auto.tfvars.json . -ln -s ~/fast-config/tfvars/02-networking.auto.tfvars.json . -# also copy the tfvars file used for the bootstrap stage -cp ../../0-bootstrap/terraform.tfvars . -``` +The full list can be found in the [Variables](#variables) table at the bottom of this document. -If you're not using FAST or its output files, refer to the [Variables](#variables) table at the bottom of this document for a full list of variables, their origin (e.g., a stage or specific to this one), and descriptions explaining their meaning. +### Running the stage -Once the configuration is complete you can apply this stage: +Once provider and variable values are in place and the correct user is configured, the stage can be run: ```bash terraform init terraform apply ``` +### Running in isolation + +This stage can be run in isolation by providing the necessary variables, but it's really meant to be used as part of the FAST flow after the "foundational stages" ([`0-bootstrap`](../../0-bootstrap), [`1-resman`](../../1-resman), [`2-networking`](../../2-networking-b-vpn) and [`2-security`](../../2-security)). + +When running in isolation, the following roles are needed on the principal used to apply Terraform: + +- on the organization or network folder level + - `roles/xpnAdmin` or a custom role which includes the following permissions + - `"compute.organizations.enableXpnResource"`, + - `"compute.organizations.disableXpnResource"`, + - `"compute.subnetworks.setIamPolicy"`, +- on each folder where projects are created + - `"roles/logging.admin"` + - `"roles/owner"` + - `"roles/resourcemanager.folderAdmin"` + - `"roles/resourcemanager.projectCreator"` +- on the host project for the Shared VPC + - `"roles/browser"` + - `"roles/compute.viewer"` +- on the organization or billing account + - `roles/billing.admin` + +The VPC host project, VPC and subnets should already exist. + ## Demo pipeline The application layer is out of scope of this script. As a demo purpuse only, several Cloud Composer DAGs are provided. Demos will import data from the `landing` area to the `DataWarehouse Confidential` dataset suing different features. diff --git a/fast/stages/3-data-platform/dev/main.tf b/fast/stages/3-data-platform/dev/main.tf index 53d901d1be..c600a7586f 100644 --- a/fast/stages/3-data-platform/dev/main.tf +++ b/fast/stages/3-data-platform/dev/main.tf @@ -18,13 +18,15 @@ module "data-platform" { source = "../../../../blueprints/data-solutions/data-platform-foundations" - billing_account_id = var.billing_account.id composer_config = var.composer_config data_force_destroy = var.data_force_destroy data_catalog_tags = var.data_catalog_tags - folder_id = var.folder_ids.data-platform-dev - groups = var.groups - location = var.location + project_config = { + billing_account_id = var.billing_account.id + parent = var.folder_ids.data-platform-dev + } + groups = var.groups + location = var.location network_config = { host_project = var.host_project_ids.dev-spoke-0 network_self_link = var.vpc_self_links.dev-spoke-0 diff --git a/fast/stages/3-gke-multitenant/dev/README.md b/fast/stages/3-gke-multitenant/dev/README.md index 4accf8e1aa..f0460c06c5 100644 --- a/fast/stages/3-gke-multitenant/dev/README.md +++ b/fast/stages/3-gke-multitenant/dev/README.md @@ -39,7 +39,68 @@ This stage creates a project containing and as many clusters and node pools as r ## How to run this stage -This stage is meant to be executed after "foundational stages" (i.e., stages [`00-bootstrap`](../../0-bootstrap), [`01-resman`](../../1-resman), 02-networking (either [VPN](../../2-networking-b-vpn) or [NVA](../../2-networking-c-nva)) and [`02-security`](../../2-security)) have been run. +This stage is meant to be executed after the FAST "foundational" stages: bootstrap, resource management, security and networking stages. + +It's of course possible to run this stage in isolation, refer to the *[Running in isolation](#running-in-isolation)* section below for details. + +Before running this stage, you need to make sure you have the correct credentials and permissions, and localize variables by assigning values that match your configuration. + +### Provider and Terraform variables + +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. + +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. + +```bash +../../../stage-links.sh ~/fast-config + +# copy and paste the following commands for '3-gke-multitenant' + +ln -s /home/ludomagno/fast-config/providers/3-gke-multitenant-providers.tf ./ +ln -s /home/ludomagno/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/1-resman.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/2-networking.auto.tfvars.json ./ +ln -s /home/ludomagno/fast-config/tfvars/2-security.auto.tfvars.json ./ +``` + +```bash +../../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '3-gke-multitenant' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/3-gke-multitenant-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-networking.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-security.auto.tfvars.json ./ +``` + +### Impersonating the automation service account + +The preconfigured provider file uses impersonation to run with this stage's automation service account's credentials. The `gcp-devops` and `organization-admins` groups have the necessary IAM bindings in place to do that, so make sure the current user is a member of one of those groups. + +### Variable configuration + +Variables in this stage -- like most other FAST stages -- are broadly divided into three separate sets: + +- variables which refer to global values for the whole organization (org id, billing account id, prefix, etc.), which are pre-populated via the `globals.auto.tfvars.json` file linked or copied above +- variables which refer to resources managed by previous stage, which are prepopulated here via the `*.auto.tfvars.json` files linked or copied above +- and finally variables that optionally control this stage's behaviour and customizations, and can to be set in a custom `terraform.tfvars` file + +The latter set is explained in the [Customization](#customizations) sections below, and the full list can be found in the [Variables](#variables) table at the bottom of this document. + +### Running the stage + +Once provider and variable values are in place and the correct user is configured, the stage can be run: + +```bash +terraform init +terraform apply +``` + +### Running in isolation It's of course possible to run this stage in isolation, by making sure the architectural prerequisites are satisfied (e.g., networking), and that the Service Account running the stage is granted the roles/permissions below: @@ -62,39 +123,9 @@ It's of course possible to run this stage in isolation, by making sure the archi The VPC host project, VPC and subnets should already exist. -### Providers configuration - -If you're running this on top of FAST, you should run the following commands to create the providers file, and populate the required variables from the previous stage. - -```bash -# Variable `outputs_location` is set to `~/fast-config` in stage 01-resman -$ cd fabric-fast/stages/03-gke-multitenant/dev -ln -s ~/fast-config/providers/03-gke-dev-providers.tf . -``` - -### Variable configuration - -There are two broad sets of variables you will need to fill in: - -- variables shared by other stages (organization id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) -- variables specific to resources managed by this stage - -#### Variables passed in from other stages +## Customizations -To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. - -If you configured a valid path for `outputs_location` in the bootstrap and networking stage, simply link the relevant `terraform-*.auto.tfvars.json` files from this stage's outputs folder (under the path you specified), where the `*` above is set to the name of the stage that produced it. For this stage, a single `.tfvars` file is available: - -```bash -# Variable `outputs_location` is set to `~/fast-config` -ln -s ~/fast-config/tfvars/00-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/01-resman.auto.tfvars.json . -ln -s ~/fast-config/tfvars/02-networking.auto.tfvars.json . -``` - -If you're not using FAST, refer to the [Variables](#variables) table at the bottom of this document for a full list of variables, their origin (e.g., a stage or specific to this one), and descriptions explaining their meaning. - -#### Cluster and node pools +### Cluster and node pools This stage is designed with multi-tenancy in mind, and the expectation is that GKE clusters will mostly share a common set of defaults. Variables are designed to support this approach for both clusters and node pools: @@ -105,7 +136,7 @@ This stage is designed with multi-tenancy in mind, and the expectation is that There are two additional variables that influence cluster configuration: `authenticator_security_group` to configure [Google Groups for RBAC](https://cloud.google.com/kubernetes-engine/docs/how-to/google-groups-rbac), `dns_domain` to configure [Cloud DNS for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/cloud-dns). -#### Fleet management +### Fleet management Fleet management is entirely optional, and uses three separate variables: @@ -116,15 +147,6 @@ Fleet management is entirely optional, and uses three separate variables: Leave all these variables unset (or set to `null`) to disable fleet management. -## Running Terraform - -Once the [provider](#providers-configuration) and [variable](#variable-configuration) configuration is complete, you can apply this stage: - -```bash -terraform init -terraform apply -``` - diff --git a/fast/stages/3-project-factory/dev/data/projects/project.yaml.sample b/fast/stages/3-project-factory/dev/data/projects/project.yaml.sample index 88ba0bf50a..5311019d82 100644 --- a/fast/stages/3-project-factory/dev/data/projects/project.yaml.sample +++ b/fast/stages/3-project-factory/dev/data/projects/project.yaml.sample @@ -48,15 +48,18 @@ labels: # [opt] Org policy overrides defined at project level org_policies: - constraints/compute.disableGuestAttributesAccess: - enforce: true - constraints/compute.trustedImageProjects: - allow: - values: + compute.disableGuestAttributesAccess: + rules: + - enforce: true + compute.trustedImageProjects: + rules: + - allow: + values: - projects/fast-dev-iac-core-0 - constraints/compute.vmExternalIpAccess: - deny: - all: true + compute.vmExternalIpAccess: + rules: + - deny: + all: true # [opt] Service account to create for the project and their roles on the project # in name => [roles] format diff --git a/fast/stages/CLEANUP.md b/fast/stages/CLEANUP.md index 3bc581f92a..4b2667c838 100644 --- a/fast/stages/CLEANUP.md +++ b/fast/stages/CLEANUP.md @@ -7,7 +7,7 @@ Destruction must be done in reverse order, from stage 3 to stage 0 ## Stage 3 (Project Factory) ```bash -cd $FAST_PWD/03-project-factory/prod/ +cd $FAST_PWD/3-project-factory/dev/ terraform destroy ``` @@ -16,7 +16,7 @@ terraform destroy Terraform refuses to delete non-empty GCS buckets and BigQuery datasets, so they need to be removed manually from the state. ```bash -cd $FAST_PWD/03-project-factory/prod/ +cd $FAST_PWD/3-gke-multitenant/dev/ # remove BQ dataset manually for x in $(terraform state list | grep google_bigquery_dataset); do @@ -29,14 +29,14 @@ terraform destroy ## Stage 2 (Security) ```bash -cd $FAST_PWD/02-security/ +cd $FAST_PWD/2-security/ terraform destroy ``` ## Stage 2 (Networking) ```bash -cd $FAST_PWD/02-networking-XXX/ +cd $FAST_PWD/2-networking-XXX/ terraform destroy ``` @@ -47,7 +47,7 @@ A minor glitch can surface running `terraform destroy`, where the service projec Stage 1 is a little more complicated because of the GCS buckets containing your terraform statefiles. By default, Terraform refuses to delete non-empty buckets, which is good to protect your terraform state, but it makes destruction a bit harder. Use the commands below to remove the GCS buckets from the state and then execute `terraform destroy` ```bash -cd $FAST_PWD/01-resman/ +cd $FAST_PWD/1-resman/ # remove buckets from state since terraform refuses to delete them for x in $(terraform state list | grep google_storage_bucket.bucket); do @@ -64,10 +64,10 @@ terraform destroy Just like before, we manually remove several resources (GCS buckets and BQ datasets). Note that `terrafom destroy` will fail. This is expected; just continue with the rest of the steps. ```bash -cd $FAST_PWD/00-bootstrap/ +cd $FAST_PWD/0-bootstrap/ # remove provider config to execute without SA impersonation -rm 00-bootstrap-providers.tf +rm 0-bootstrap-providers.tf # migrate to local state terraform init -migrate-state diff --git a/fast/stages/COMPANION.md b/fast/stages/COMPANION.md index d5d7752f2e..96506d0083 100644 --- a/fast/stages/COMPANION.md +++ b/fast/stages/COMPANION.md @@ -8,7 +8,7 @@ The detailed explanation of each stage, their configuration, possible modificati ## Prerequisites -1. FAST uses the recommended groups from the [GCP Enterprise Setup checklist](). Go to [Workspace / Cloud Identity](https://admin.google.com) and ensure all the following groups exist: +1. FAST uses the recommended groups from the [GCP Enterprise Setup checklist](https://cloud.google.com/docs/enterprise/setup-checklist). Go to [Workspace / Cloud Identity](https://admin.google.com) and ensure all the following groups exist: - `gcp-billing-admins@` - `gcp-devops@` @@ -80,8 +80,8 @@ If you are using a billing account in a different organization, please follow [t This initial stage will create common projects for IaC, Logging & Billing, and bootstrap IAM policies. ```bash -# move to the 00-bootstrap directory -cd $FAST_PWD/00-bootstrap +# move to the 0-bootstrap directory +cd $FAST_PWD/0-bootstrap # copy the template terraform tfvars file and save as `terraform.tfvars` # then edit to match your environment! @@ -114,11 +114,12 @@ outputs_location = "~/fast-config" terraform init terraform apply -var bootstrap_user=$FAST_BU -# link the generated provider file -ln -s ~/fast-config/providers/0-0-bootstrap* . +# link providers file +ln -s ~/fast-config/providers/0-bootstrap-providers.tf ./ # re-run init and apply to remove user-level IAM terraform init -migrate-state + # answer 'yes' to terraform's question terraform apply ``` @@ -132,14 +133,14 @@ This stage performs two important tasks: ```bash # move to the 01-resman directory -cd $FAST_PWD/01-resman +cd $FAST_PWD/1-resman -# Link providers and variables from previous stages -ln -s ~/fast-config/providers/1-0-resman-providers.tf . -ln -s ~/fast-config/tfvars/0-0-bootstrap.auto.tfvars.json . +# link providers and variables from previous stages +ln -s ~/fast-config/providers/1-resman-providers.tf . +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json . ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -# Edit your terraform.tfvars to append Teams configuration (optional) +# edit your terraform.tfvars to append Teams configuration (optional) edit terraform.tfvars ``` @@ -178,15 +179,15 @@ In this stage, we will deploy one of the 3 available Hub&Spoke networking topolo ```bash # move to the 02-networking-XXX directory (where XXX should be one of vpn|peering|nva) -cd $FAST_PWD/02-networking-XXX +cd $FAST_PWD/2-networking-XXX # setup providers and variables from previous stages -ln -s ~/fast-config/providers/2-0-networking-providers.tf . -ln -s ~/fast-config/tfvars/0-0-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/1-0-resman.auto.tfvars.json . +ln -s ~/fast-config/providers/2-networking-providers.tf . +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json . +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json . ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -# Create terraform.tfvars. output_location variable is required to generate networking stage output file +# create terraform.tfvars. output_location variable is required to generate networking stage output file edit terraform.tfvars ``` @@ -212,12 +213,12 @@ This stage sets up security resources (KMS and VPC-SC) and configurations which cd $FAST_PWD/02-security # link providers and variables from previous stages -ln -s ~/fast-config/providers/2-0-security-providers.tf . -ln -s ~/fast-config/tfvars/0-0-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/1-0-resman.auto.tfvars.json . +ln -s ~/fast-config/providers/2-security-providers.tf . +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json . +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json . ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -# Edit terraform.tfvars to include KMS and/or VPC-SC configuration +# edit terraform.tfvars to include KMS and/or VPC-SC configuration edit terraform.tfvars ``` @@ -234,19 +235,20 @@ terraform apply The Project Factory stage builds on top of your foundations to create and set up projects (and related resources) to be used for your workloads. It is organized in folders representing environments (e.g. "dev", "prod"), each implemented by a stand-alone terraform resource factory. ```bash -# Variable `outputs_location` is set to `~/fast-config` -cd $FAST_PWD/3-0-project-factory/ENVIRONMENT -ln -s ~/fast-config/providers/3-0-project-factory-ENVIRONMENT-providers.tf . +# variable `outputs_location` is set to `~/fast-config` +cd $FAST_PWD/3-project-factory/ENVIRONMENT +ln -s ~/fast-config/providers/3-project-factory-ENVIRONMENT-providers.tf . -ln -s ~/fast-config/tfvars/0-0-bootstrap.auto.tfvars.json . -ln -s ~/fast-config/tfvars/1-0-resman.auto.tfvars.json . -ln -s ~/fast-config/tfvars/2-0-networking.auto.tfvars.json . +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json . +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json . +ln -s ~/fast-config/tfvars/2-networking.auto.tfvars.json . ln -s ~/fast-config/tfvars/globals.auto.tfvars.json . -# Define your environment default values (eg for billing alerts and labels) +# define your environment default values (eg for billing alerts and labels) edit data/defaults.yaml -# Create one yaml file per project to be created. Yaml file will include project configuration. Projects will be named after the filename +# create one YAML file per project to be created with project configuration +# filenames will be used for project ids cp data/projects/project.yaml.sample data/projects/YOUR_PROJECT_NAME.yaml edit data/projects/YOUR_PROJECT_NAME.yaml diff --git a/fast/stages/FAQ.md b/fast/stages/FAQ.md index bd9559d481..5245c8a965 100644 --- a/fast/stages/FAQ.md +++ b/fast/stages/FAQ.md @@ -1,29 +1,13 @@ - -## 00-bootstrap - -1. How to handle requests where automation, logging and/or billing export projects are not under organization but in different folders. - - Run bootstrap stage and let automation, logging and/or billing projects be created under organization. - - Run resource manager stage or any other custom stage which creates the folders where these projects will reside. - - Once folders are created add folder ids to varibale "project_parent_ids" in bootstrap stage and run bootstrap stage. - - This step will move the projects from organization to the parent folders specificed. - -## cicd - -1. Why do we need two seperate ServiceAccounts when configuring cicd pipelines (cicd SA and IaC SA) - - Having seperate service accounts helps shutdown the pipeline incase of any issues and still keep IaC SA and ability to run terraform plan/apply manually. - - A pipeline can only generate a token that can get access to an SA. It cannot directly call a provider file to impersonate IaC SA. - - Having providers file that allows impersonation to IaC SA allows flexibility to run terraform manually or from CICD Pipelines. - ![CICD SA and IaC SA](IaC_SA.png) - -## Authenciation - -1. If you are seeing "Permission Issues" when doing terraform apply and the identity with which you are running terraform has correct permissions; - run below command so that correct auth credentials are picked by ADC when terraform commands are executed - - ````bash - gcloud auth application-default login - ```` - - - Refer to [GCP Authentication](https://cloud.google.com/docs/authentication - ) and [Terraform Provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference) for more information +# FAST Mini FAQ + +- **How can the automation, logging and/or billing export projects be placed under specific folders instead of the org?** + - Run the bootstrap stage and let automation, logging and/or billing projects be created under the organization. + - Add the needed folders to the resource manager stage, or create them outside the stage in the console/gcloud or from a custom Terraform setup. + - Once folders have been created go back to the bootstrap stage, and edit your tfvars file by adding their ids to the `project_parent_ids` variable. + - Run the bootstrap stage again, the projects will be moved under the desired folders. +- **Why do we need two separate service accounts when configuring CI/CD pipelines (CI/CD SA and IaC SA)?** + - To have the pipeline workflow follow the same impersonation flow ([CI/CD SA impersonates IaC SA](IaC_SA.png)) used when applying Terraform manually (user impersonates IaC SA), which allows the pipeline to consume the same auto-generated provider files. + - To allow disabling pipeline credentials in case of issues with a single operation, by removing the ability of the CI/CD SA to impersonate the IaC SA. +- **How can I fix permission issues when running Terraform apply?** + - Make sure your account is part of the organization admin group defined in variables. + - Make sure you have configured [application default credentials](https://cloud.google.com/docs/authentication/application-default-credentials), rerun `gcloud auth login --update-adc` to fix them. diff --git a/modules/README.md b/modules/README.md index f5ed3c9c91..955c526b69 100644 --- a/modules/README.md +++ b/modules/README.md @@ -72,6 +72,7 @@ These modules are used in the examples included in this repository. If you are u - [Cloud SQL instance](./cloudsql-instance) - [Data Catalog Policy Tag](./data-catalog-policy-tag) - [Datafusion](./datafusion) +- [Dataproc](./dataproc) - [GCS](./gcs) - [Pub/Sub](./pubsub) diff --git a/modules/__experimental/net-neg/versions.tf b/modules/__experimental/net-neg/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/__experimental/net-neg/versions.tf +++ b/modules/__experimental/net-neg/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/api-gateway/versions.tf b/modules/api-gateway/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/api-gateway/versions.tf +++ b/modules/api-gateway/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/apigee/versions.tf b/modules/apigee/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/apigee/versions.tf +++ b/modules/apigee/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/artifact-registry/versions.tf b/modules/artifact-registry/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/artifact-registry/versions.tf +++ b/modules/artifact-registry/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/bigquery-dataset/README.md b/modules/bigquery-dataset/README.md index 381ffab7ce..6dbd120c20 100644 --- a/modules/bigquery-dataset/README.md +++ b/modules/bigquery-dataset/README.md @@ -67,6 +67,7 @@ module "bigquery-dataset" { default_table_expiration_ms = 3600000 default_partition_expiration_ms = null delete_contents_on_destroy = false + max_time_travel_hours = 168 } } # tftest modules=1 resources=1 @@ -178,7 +179,7 @@ module "bigquery-dataset" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| | [id](variables.tf#L69) | Dataset id. | string | ✓ | | -| [project_id](variables.tf#L100) | Id of the project where datasets will be created. | string | ✓ | | +| [project_id](variables.tf#L97) | Id of the project where datasets will be created. | string | ✓ | | | [access](variables.tf#L17) | Map of access rules with role and identity type. Keys are arbitrary and must match those in the `access_identities` variable, types are `domain`, `group`, `special_group`, `user`, `view`. | map(object({…})) | | {} | | [access_identities](variables.tf#L33) | Map of access identities used for basic access roles. View identities have the format 'project_id\|dataset_id\|table_id'. | map(string) | | {} | | [dataset_access](variables.tf#L39) | Set access in the dataset resource instead of using separate resources. | bool | | false | @@ -188,9 +189,9 @@ module "bigquery-dataset" { | [iam](variables.tf#L63) | IAM bindings in {ROLE => [MEMBERS]} format. Mutually exclusive with the access_* variables used for basic roles. | map(list(string)) | | {} | | [labels](variables.tf#L74) | Dataset labels. | map(string) | | {} | | [location](variables.tf#L80) | Dataset location. | string | | "EU" | -| [options](variables.tf#L86) | Dataset options. | object({…}) | | {…} | -| [tables](variables.tf#L105) | Table definitions. Options and partitioning default to null. Partitioning can only use `range` or `time`, set the unused one to null. | map(object({…})) | | {} | -| [views](variables.tf#L133) | View definitions. | map(object({…})) | | {} | +| [options](variables.tf#L86) | Dataset options. | object({…}) | | {} | +| [tables](variables.tf#L102) | Table definitions. Options and partitioning default to null. Partitioning can only use `range` or `time`, set the unused one to null. | map(object({…})) | | {} | +| [views](variables.tf#L130) | View definitions. | map(object({…})) | | {} | ## Outputs diff --git a/modules/bigquery-dataset/main.tf b/modules/bigquery-dataset/main.tf index 47f8fcb53b..f832cd85c3 100644 --- a/modules/bigquery-dataset/main.tf +++ b/modules/bigquery-dataset/main.tf @@ -42,7 +42,7 @@ resource "google_bigquery_dataset" "default" { delete_contents_on_destroy = var.options.delete_contents_on_destroy default_table_expiration_ms = var.options.default_table_expiration_ms default_partition_expiration_ms = var.options.default_partition_expiration_ms - + max_time_travel_hours = var.options.max_time_travel_hours dynamic "access" { for_each = var.dataset_access ? local.access_domain : {} content { diff --git a/modules/bigquery-dataset/variables.tf b/modules/bigquery-dataset/variables.tf index 5f8028abfb..b44b66585b 100644 --- a/modules/bigquery-dataset/variables.tf +++ b/modules/bigquery-dataset/variables.tf @@ -86,15 +86,12 @@ variable "location" { variable "options" { description = "Dataset options." type = object({ - default_table_expiration_ms = number - default_partition_expiration_ms = number - delete_contents_on_destroy = bool + default_table_expiration_ms = optional(number, null) + default_partition_expiration_ms = optional(number, null) + delete_contents_on_destroy = optional(bool, false) + max_time_travel_hours = optional(number, 168) }) - default = { - default_table_expiration_ms = null - default_partition_expiration_ms = null - delete_contents_on_destroy = false - } + default = {} } variable "project_id" { diff --git a/modules/bigquery-dataset/versions.tf b/modules/bigquery-dataset/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/bigquery-dataset/versions.tf +++ b/modules/bigquery-dataset/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/bigtable-instance/versions.tf b/modules/bigtable-instance/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/bigtable-instance/versions.tf +++ b/modules/bigtable-instance/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/billing-budget/versions.tf b/modules/billing-budget/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/billing-budget/versions.tf +++ b/modules/billing-budget/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/binauthz/versions.tf b/modules/binauthz/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/binauthz/versions.tf +++ b/modules/binauthz/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/__need_fixing/onprem/versions.tf b/modules/cloud-config-container/__need_fixing/onprem/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/__need_fixing/onprem/versions.tf +++ b/modules/cloud-config-container/__need_fixing/onprem/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/coredns/versions.tf b/modules/cloud-config-container/coredns/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/coredns/versions.tf +++ b/modules/cloud-config-container/coredns/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/cos-generic-metadata/versions.tf b/modules/cloud-config-container/cos-generic-metadata/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/cos-generic-metadata/versions.tf +++ b/modules/cloud-config-container/cos-generic-metadata/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/envoy-traffic-director/versions.tf b/modules/cloud-config-container/envoy-traffic-director/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/envoy-traffic-director/versions.tf +++ b/modules/cloud-config-container/envoy-traffic-director/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/mysql/versions.tf b/modules/cloud-config-container/mysql/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/mysql/versions.tf +++ b/modules/cloud-config-container/mysql/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/nginx-tls/versions.tf b/modules/cloud-config-container/nginx-tls/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/nginx-tls/versions.tf +++ b/modules/cloud-config-container/nginx-tls/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/nginx/versions.tf b/modules/cloud-config-container/nginx/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/nginx/versions.tf +++ b/modules/cloud-config-container/nginx/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/simple-nva/versions.tf b/modules/cloud-config-container/simple-nva/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/simple-nva/versions.tf +++ b/modules/cloud-config-container/simple-nva/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-config-container/squid/versions.tf b/modules/cloud-config-container/squid/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-config-container/squid/versions.tf +++ b/modules/cloud-config-container/squid/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-function/versions.tf b/modules/cloud-function/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-function/versions.tf +++ b/modules/cloud-function/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-identity-group/versions.tf b/modules/cloud-identity-group/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-identity-group/versions.tf +++ b/modules/cloud-identity-group/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloud-run/versions.tf b/modules/cloud-run/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloud-run/versions.tf +++ b/modules/cloud-run/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/cloudsql-instance/versions.tf b/modules/cloudsql-instance/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/cloudsql-instance/versions.tf +++ b/modules/cloudsql-instance/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/compute-mig/health-check.tf b/modules/compute-mig/health-check.tf index 4a4ed40def..88f9f6ea73 100644 --- a/modules/compute-mig/health-check.tf +++ b/modules/compute-mig/health-check.tf @@ -76,13 +76,13 @@ resource "google_compute_health_check" "default" { dynamic "https_health_check" { for_each = local.hc_https ? [""] : [] content { - host = local.hc.http.host - port = local.hc.http.port - port_name = local.hc.http.port_name - port_specification = local.hc.http.port_specification - proxy_header = local.hc.http.proxy_header - request_path = local.hc.http.request_path - response = local.hc.http.response + host = local.hc.https.host + port = local.hc.https.port + port_name = local.hc.https.port_name + port_specification = local.hc.https.port_specification + proxy_header = local.hc.https.proxy_header + request_path = local.hc.https.request_path + response = local.hc.https.response } } diff --git a/modules/compute-mig/versions.tf b/modules/compute-mig/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/compute-mig/versions.tf +++ b/modules/compute-mig/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/compute-vm/versions.tf b/modules/compute-vm/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/compute-vm/versions.tf +++ b/modules/compute-vm/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/container-registry/versions.tf b/modules/container-registry/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/container-registry/versions.tf +++ b/modules/container-registry/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/data-catalog-policy-tag/versions.tf b/modules/data-catalog-policy-tag/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/data-catalog-policy-tag/versions.tf +++ b/modules/data-catalog-policy-tag/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/datafusion/versions.tf b/modules/datafusion/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/datafusion/versions.tf +++ b/modules/datafusion/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/dataproc/README.md b/modules/dataproc/README.md new file mode 100644 index 0000000000..d071ecdaad --- /dev/null +++ b/modules/dataproc/README.md @@ -0,0 +1,168 @@ +# Google Cloud Dataproc + +This module Manages a Google Cloud [Dataproc](https://cloud.google.com/dataproc) cluster resource, including IAM. + +## TODO + +- [ ] Add support for Cloud Dataproc [autoscaling policy](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dataproc_autoscaling_policy_iam). + +## Examples + +### Simple + +```hcl +module "processing-dp-cluster-2" { + source = "./fabric/modules/dataproc" + project_id = "my-project" + name = "my-cluster" + region = "europe-west1" +} +# tftest modules=1 resources=1 +``` + +### Cluster configuration + +To set cluster configuration use the 'dataproc_config.cluster_config' variable. + +```hcl +module "processing-dp-cluster" { + source = "./fabric/modules/dataproc" + project_id = "my-project" + name = "my-cluster" + region = "europe-west1" + prefix = "prefix" + dataproc_config = { + cluster_config = { + gce_cluster_config = { + subnetwork = "https://www.googleapis.com/compute/v1/projects/PROJECT/regions/europe-west1/subnetworks/SUBNET" + zone = "europe-west1-b" + service_account = "" + service_account_scopes = ["cloud-platform"] + internal_ip_only = true + } + } + } +} +# tftest modules=1 resources=1 +``` + +### Cluster with CMEK encryption + +To set cluster configuration use the Customer Managed Encryption key, set `dataproc_config.encryption_config.` variable. The Compute Engine service agent and the Cloud Storage service agent need to have `CryptoKey Encrypter/Decrypter` role on they configured KMS key ([Documentation](https://cloud.google.com/dataproc/docs/concepts/configuring-clusters/customer-managed-encryption)). + +```hcl +module "processing-dp-cluster" { + source = "./fabric/modules/dataproc" + project_id = "my-project" + name = "my-cluster" + region = "europe-west1" + prefix = "prefix" + dataproc_config = { + cluster_config = { + gce_cluster_config = { + subnetwork = "https://www.googleapis.com/compute/v1/projects/PROJECT/regions/europe-west1/subnetworks/SUBNET" + zone = "europe-west1-b" + service_account = "" + service_account_scopes = ["cloud-platform"] + internal_ip_only = true + } + } + encryption_config = { + kms_key_name = "projects/project-id/locations/region/keyRings/key-ring-name/cryptoKeys/key-name" + } + } +} +# tftest modules=1 resources=1 +``` + +## IAM Examples + +IAM is managed via several variables that implement different levels of control: + +- `group_iam` and `iam` configure authoritative bindings that manage individual roles exclusively, mapping to the `google_dataproc_cluster_iam_binding` resource +- `iam_additive` configure additive bindings that only manage individual role/member pairs, mapping to the `google_dataproc_cluster_iam_member` resource + +### Authoritative IAM + +The iam variable is based on role keys and is typically used for service accounts, or where member values can be dynamic and would create potential problems in the underlying for_each cycle. + +```hcl +module "processing-dp-cluster" { + source = "./fabric/modules/dataproc" + project_id = "my-project" + name = "my-cluster" + region = "europe-west1" + prefix = "prefix" + iam = { + "roles/dataproc.viewer" = [ + "serviceAccount:service-account@PROJECT_ID.iam.gserviceaccount.com" + ] + } +} +# tftest modules=1 resources=2 +``` + +The group_iam variable uses group email addresses as keys and is a convenient way to assign roles to humans following Google's best practices. The end result is readable code that also serves as documentation. + +```hcl +module "processing-dp-cluster" { + source = "./fabric/modules/dataproc" + project_id = "my-project" + name = "my-cluster" + region = "europe-west1" + prefix = "prefix" + group_iam = { + "gcp-data-engineers@example.net" = [ + "roles/dataproc.viewer" + ] + } +} +# tftest modules=1 resources=2 +``` + +### Additive IAM + +Additive IAM is typically used where bindings for specific roles are controlled by different modules or in different Terraform stages. One example is when the cluster is created by one team but a different team manages access. + +```hcl +module "processing-dp-cluster" { + source = "./fabric/modules/dataproc" + project_id = "my-project" + name = "my-cluster" + region = "europe-west1" + prefix = "prefix" + iam_additive = { + "roles/dataproc.viewer" = [ + "serviceAccount:service-account@PROJECT_ID.iam.gserviceaccount.com" + ] + } +} +# tftest modules=1 resources=2 +``` + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [name](variables.tf#L211) | Cluster name. | string | ✓ | | +| [project_id](variables.tf#L226) | Project ID. | string | ✓ | | +| [region](variables.tf#L231) | Dataproc region. | string | ✓ | | +| [dataproc_config](variables.tf#L17) | Dataproc cluster config. | object({…}) | | {} | +| [group_iam](variables.tf#L184) | Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable. | map(list(string)) | | {} | +| [iam](variables.tf#L191) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [iam_additive](variables.tf#L198) | IAM additive bindings in {ROLE => [MEMBERS]} format. | map(list(string)) | | {} | +| [labels](variables.tf#L205) | The resource labels for instance to use to annotate any related underlying resources, such as Compute Engine VMs. | map(string) | | {} | +| [prefix](variables.tf#L216) | Optional prefix used to generate project id and name. | string | | null | +| [service_account](variables.tf#L236) | Service account to set on the Dataproc cluster. | string | | null | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [bucket_names](outputs.tf#L19) | List of bucket names which have been assigned to the cluster. | | +| [http_ports](outputs.tf#L24) | The map of port descriptions to URLs. | | +| [instance_names](outputs.tf#L29) | List of instance names which have been assigned to the cluster. | | +| [name](outputs.tf#L38) | The name of the cluster. | | + + diff --git a/modules/dataproc/iam.tf b/modules/dataproc/iam.tf new file mode 100644 index 0000000000..e44c2a6374 --- /dev/null +++ b/modules/dataproc/iam.tf @@ -0,0 +1,67 @@ +/** + * Copyright 2022 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. + */ + +# # tfdoc:file:description Generic IAM bindings and roles. + +locals { + _group_iam_roles = distinct(flatten(values(var.group_iam))) + _group_iam = { + for r in local._group_iam_roles : r => [ + for k, v in var.group_iam : "group:${k}" if try(index(v, r), null) != null + ] + } + _iam_additive_pairs = flatten([ + for role, members in var.iam_additive : [ + for member in members : { role = role, member = member } + ] + ]) + iam = { + for role in distinct(concat(keys(var.iam), keys(local._group_iam))) : + role => concat( + try(var.iam[role], []), + try(local._group_iam[role], []) + ) + } + iam_additive = { + for pair in local._iam_additive_pairs : + "${pair.role}-${pair.member}" => { + role = pair.role + member = pair.member + } + } +} + +resource "google_dataproc_cluster_iam_binding" "authoritative" { + for_each = local.iam + project = var.project_id + cluster = google_dataproc_cluster.cluster.name + region = var.region + role = each.key + members = each.value +} + +resource "google_dataproc_cluster_iam_member" "additive" { + for_each = ( + length(var.iam_additive) > 0 + ? local.iam_additive + : {} + ) + project = var.project_id + cluster = google_dataproc_cluster.cluster.name + region = var.region + role = each.value.role + member = each.value.member +} diff --git a/modules/dataproc/main.tf b/modules/dataproc/main.tf new file mode 100644 index 0000000000..55bef5c70e --- /dev/null +++ b/modules/dataproc/main.tf @@ -0,0 +1,298 @@ +/** + * Copyright 2022 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. + */ + +# tfdoc:file:description Cloud Dataproc resource definition. + +locals { + prefix = var.prefix == null ? "" : "${var.prefix}-" +} + +resource "google_dataproc_cluster" "cluster" { + name = "${local.prefix}${var.name}" + project = var.project_id + region = var.region + graceful_decommission_timeout = var.dataproc_config.graceful_decommission_timeout + labels = var.labels + dynamic "cluster_config" { + for_each = var.dataproc_config.cluster_config == null ? [] : [""] + content { + staging_bucket = var.dataproc_config.cluster_config.staging_bucket + temp_bucket = var.dataproc_config.cluster_config.temp_bucket + dynamic "gce_cluster_config" { + for_each = var.dataproc_config.cluster_config.gce_cluster_config == null ? [] : [""] + content { + zone = var.dataproc_config.cluster_config.gce_cluster_config.zone + network = var.dataproc_config.cluster_config.gce_cluster_config.network + subnetwork = var.dataproc_config.cluster_config.gce_cluster_config.subnetwork + service_account = var.dataproc_config.cluster_config.gce_cluster_config.service_account + service_account_scopes = var.dataproc_config.cluster_config.gce_cluster_config.service_account_scopes + tags = var.dataproc_config.cluster_config.gce_cluster_config.tags + internal_ip_only = var.dataproc_config.cluster_config.gce_cluster_config.internal_ip_only + metadata = var.dataproc_config.cluster_config.gce_cluster_config.metadata + dynamic "reservation_affinity" { + for_each = var.dataproc_config.cluster_config.gce_cluster_config.reservation_affinity == null ? [] : [""] + content { + consume_reservation_type = var.dataproc_config.cluster_config.gce_cluster_config.reservation_affinity.consume_reservation_type + key = var.dataproc_config.cluster_config.gce_cluster_config.reservation_affinity.key + values = var.dataproc_config.cluster_config.gce_cluster_config.reservation_affinity.value + } + } + dynamic "node_group_affinity" { + for_each = var.dataproc_config.cluster_config.gce_cluster_config.node_group_affinity == null ? [] : [""] + content { + node_group_uri = var.dataproc_config.cluster_config.gce_cluster_config.node_group_uri + } + } + dynamic "shielded_instance_config" { + for_each = var.dataproc_config.cluster_config.gce_cluster_config.shielded_instance_config == null ? [] : [""] + content { + enable_secure_boot = var.dataproc_config.cluster_config.gce_cluster_config.shielded_instance_config.enable_secure_boot + enable_vtpm = var.dataproc_config.cluster_config.gce_cluster_config.shielded_instance_config.enable_vtpm + enable_integrity_monitoring = var.dataproc_config.cluster_config.gce_cluster_config.shielded_instance_config.enable_integrity_monitoring + } + } + } + } + dynamic "master_config" { + for_each = var.dataproc_config.cluster_config.master_config == null ? [] : [""] + content { + num_instances = var.dataproc_config.cluster_config.master_config.num_instances + machine_type = var.dataproc_config.cluster_config.master_config.machine_type + min_cpu_platform = var.dataproc_config.cluster_config.master_config.min_cpu_platform + image_uri = var.dataproc_config.cluster_config.master_config.image_uri + dynamic "disk_config" { + for_each = var.dataproc_config.cluster_config.master_config.disk_config == null ? [] : [""] + content { + boot_disk_type = var.dataproc_config.cluster_config.master_config.disk_config.boot_disk_type + boot_disk_size_gb = var.dataproc_config.cluster_config.master_config.disk_config.boot_disk_size_gb + num_local_ssds = var.dataproc_config.cluster_config.master_config.disk_config.num_local_ssds + } + } + dynamic "accelerators" { + for_each = var.dataproc_config.cluster_config.master_config.accelerators == null ? [] : [""] + content { + accelerator_type = var.dataproc_config.cluster_config.master_config.accelerators.accelerator_type + accelerator_count = var.dataproc_config.cluster_config.master_config.accelerators.accelerator_count + } + } + } + } + dynamic "worker_config" { + for_each = var.dataproc_config.cluster_config.worker_config == null ? [] : [""] + content { + num_instances = var.dataproc_config.cluster_config.worker_config.num_instances + machine_type = var.dataproc_config.cluster_config.worker_config.machine_type + min_cpu_platform = var.dataproc_config.cluster_config.worker_config.min_cpu_platform + dynamic "disk_config" { + for_each = var.dataproc_config.cluster_config.worker_config.disk_config == null ? [] : [""] + content { + boot_disk_type = var.dataproc_config.cluster_config.worker_config.disk_config.boot_disk_type + boot_disk_size_gb = var.dataproc_config.cluster_config.worker_config.disk_config.boot_disk_size_gb + num_local_ssds = var.dataproc_config.cluster_config.worker_config.disk_config.num_local_ssds + } + } + image_uri = var.dataproc_config.cluster_config.worker_config.image_uri + dynamic "accelerators" { + for_each = var.dataproc_config.cluster_config.worker_config.accelerators == null ? [] : [""] + content { + accelerator_type = var.dataproc_config.cluster_config.accelerators.accelerator_type + accelerator_count = var.dataproc_config.cluster_config.accelerators.accelerator_count + } + } + } + } + dynamic "preemptible_worker_config" { + for_each = var.dataproc_config.cluster_config.preemptible_worker_config == null ? [] : [""] + content { + num_instances = var.dataproc_config.cluster_config.preemptible_worker_config.num_instances + preemptibility = var.dataproc_config.cluster_config.preemptible_worker_config.preemptibility + dynamic "disk_config" { + for_each = var.dataproc_config.cluster_config.preemptible_worker_config.disk_config == null ? [] : [""] + content { + boot_disk_type = var.dataproc_config.cluster_config.disk_config.boot_disk_type + boot_disk_size_gb = var.dataproc_config.cluster_config.disk_config.boot_disk_size_gb + num_local_ssds = var.dataproc_config.cluster_config.disk_config.num_local_ssds + } + } + } + } + dynamic "software_config" { + for_each = var.dataproc_config.cluster_config.software_config == null ? [] : [""] + content { + image_version = var.dataproc_config.cluster_config.software_config.image_version + override_properties = var.dataproc_config.cluster_config.software_config.override_properties + optional_components = var.dataproc_config.cluster_config.software_config.optional_components + } + } + dynamic "security_config" { + for_each = var.dataproc_config.cluster_config.security_config == null ? [] : [""] + content { + dynamic "kerberos_config" { + for_each = try(var.dataproc_config.cluster_config.security_config.kerberos_config == null ? [] : [""], []) + content { + cross_realm_trust_admin_server = var.dataproc_config.cluster_config.kerberos_config.cross_realm_trust_admin_server + cross_realm_trust_kdc = var.dataproc_config.cluster_config.kerberos_config.cross_realm_trust_kdc + cross_realm_trust_realm = var.dataproc_config.cluster_config.kerberos_config.cross_realm_trust_realm + cross_realm_trust_shared_password_uri = var.dataproc_config.cluster_config.kerberos_config.cross_realm_trust_shared_password_uri + enable_kerberos = var.dataproc_config.cluster_config.kerberos_config.enable_kerberos + kdc_db_key_uri = var.dataproc_config.cluster_config.kerberos_config.kdc_db_key_uri + key_password_uri = var.dataproc_config.cluster_config.kerberos_config.key_password_uri + keystore_uri = var.dataproc_config.cluster_config.kerberos_config.keystore_uri + keystore_password_uri = var.dataproc_config.cluster_config.kerberos_config.keystore_password_uri + kms_key_uri = var.dataproc_config.cluster_config.kerberos_config.kms_key_uri + realm = var.dataproc_config.cluster_config.kerberos_config.realm + root_principal_password_uri = var.dataproc_config.cluster_config.kerberos_config.root_principal_password_uri + tgt_lifetime_hours = var.dataproc_config.cluster_config.kerberos_config.tgt_lifetime_hours + truststore_password_uri = var.dataproc_config.cluster_config.kerberos_config.truststore_password_uri + truststore_uri = var.dataproc_config.cluster_config.kerberos_config.truststore_uri + } + } + } + } + dynamic "autoscaling_config" { + for_each = var.dataproc_config.cluster_config.autoscaling_config == null ? [] : [""] + content { + policy_uri = var.dataproc_config.cluster_config.autoscaling_config.policy_uri + } + } + dynamic "initialization_action" { + for_each = var.dataproc_config.cluster_config.initialization_action == null ? [] : [""] + content { + script = var.dataproc_config.cluster_config.initialization_action.script + timeout_sec = var.dataproc_config.cluster_config.initialization_action.timeout_sec + } + } + dynamic "encryption_config" { + for_each = try(var.dataproc_config.cluster_config.encryption_config.kms_key_name == null ? [] : [""], []) + content { + kms_key_name = var.dataproc_config.cluster_config.encryption_config.kms_key_name + } + } + dynamic "dataproc_metric_config" { + for_each = var.dataproc_config.cluster_config.dataproc_metric_config == null ? [] : [""] + content { + dynamic "metrics" { + for_each = var.dataproc_config.cluster_config.dataproc_metric_config.metrics == null ? [] : [""] + content { + metric_source = var.dataproc_config.cluster_config.dataproc_metric_config.metrics.metric_source + metric_overrides = var.dataproc_config.cluster_config.dataproc_metric_config.metrics.metric_overrides + } + } + } + } + dynamic "lifecycle_config" { + for_each = var.dataproc_config.cluster_config.lifecycle_config == null ? [] : [""] + content { + idle_delete_ttl = var.dataproc_config.cluster_config.lifecycle_config.idle_delete_ttl + auto_delete_time = var.dataproc_config.cluster_config.lifecycle_config.auto_delete_time + } + } + dynamic "endpoint_config" { + for_each = var.dataproc_config.cluster_config.endpoint_config == null ? [] : [""] + content { + enable_http_port_access = var.dataproc_config.cluster_config.endpoint_config.enable_http_port_access + } + } + dynamic "metastore_config" { + for_each = var.dataproc_config.cluster_config.metastore_config == null ? [] : [""] + content { + dataproc_metastore_service = var.dataproc_config.cluster_config.metastore_config.dataproc_metastore_service + } + } + + } + } + + dynamic "virtual_cluster_config" { + for_each = var.dataproc_config.virtual_cluster_config == null ? [] : [""] + content { + dynamic "auxiliary_services_config" { + for_each = var.dataproc_config.virtual_cluster_config.auxiliary_services_config == null ? [] : [""] + content { + dynamic "metastore_config" { + for_each = var.dataproc_config.virtual_cluster_config.auxiliary_services_config.metastore_config == null ? [] : [""] + content { + dataproc_metastore_service = var.dataproc_config.virtual_cluster_config.auxiliary_services_config.metastore_config.dataproc_metastore_service + } + } + dynamic "spark_history_server_config" { + for_each = var.dataproc_config.virtual_cluster_config.auxiliary_services_config.spark_history_server_config == null ? [] : [""] + content { + dataproc_cluster = var.dataproc_config.virtual_cluster_config.auxiliary_services_config.spark_history_server_config.dataproc_cluster + } + } + } + } + dynamic "kubernetes_cluster_config" { + for_each = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config == null ? [] : [""] + content { + kubernetes_namespace = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.kubernetes_namespace + dynamic "kubernetes_software_config" { + for_each = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.kubernetes_software_config == null ? [] : [""] + content { + component_version = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.kubernetes_software_config.component_version + properties = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.kubernetes_software_config.properties + } + } + + dynamic "gke_cluster_config" { + for_each = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config == null ? [] : [""] + content { + gke_cluster_target = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.gke_cluster_target + dynamic "node_pool_target" { + for_each = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_target == null ? [] : [""] + content { + node_pool = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_target.node_pool + roles = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_target.roles + dynamic "node_pool_config" { + for_each = try(var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config == null ? [] : [""], []) + content { + dynamic "autoscaling" { + for_each = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.autoscaling == null ? [] : [""] + content { + min_node_count = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.autoscaling.min_node_count + max_node_count = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.autoscaling.max_node_count + } + } + dynamic "config" { + for_each = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.config == null ? [] : [""] + content { + machine_type = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.config.machine_type + local_ssd_count = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.config.local_ssd_count + preemptible = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.config.preemptible + min_cpu_platform = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.config.min_cpu_platform + spot = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.config.spot + } + } + locations = var.dataproc_config.virtual_cluster_config.kubernetes_cluster_config.gke_cluster_config.node_pool_config.locations + } + } + } + } + } + } + } + } + } + } + lifecycle { + ignore_changes = [ + # Some scopes are assigned in addition to the one configured + # https://cloud.google.com/dataproc/docs/concepts/configuring-clusters/service-accounts#dataproc_vm_access_scopes + cluster_config[0].gce_cluster_config[0].service_account_scopes, + ] + } +} diff --git a/modules/dataproc/outputs.tf b/modules/dataproc/outputs.tf new file mode 100644 index 0000000000..755b6dd511 --- /dev/null +++ b/modules/dataproc/outputs.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2022 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. + */ + +# tfdoc:file:description Cloud Dataproc module output. + +output "bucket_names" { + description = "List of bucket names which have been assigned to the cluster." + value = google_dataproc_cluster.cluster.cluster_config.0.bucket +} + +output "http_ports" { + description = "The map of port descriptions to URLs." + value = google_dataproc_cluster.cluster.cluster_config.0.endpoint_config.0.http_ports +} + +output "instance_names" { + description = "List of instance names which have been assigned to the cluster." + value = { + master = google_dataproc_cluster.cluster.cluster_config.0.master_config.0.instance_names + worker = google_dataproc_cluster.cluster.cluster_config.0.worker_config.0.instance_names + preemptible_worker = google_dataproc_cluster.cluster.cluster_config.0.preemptible_worker_config.0.instance_names + } +} + +output "name" { + description = "The name of the cluster." + value = google_dataproc_cluster.cluster.cluster_config.0.bucket +} + diff --git a/modules/dataproc/variables.tf b/modules/dataproc/variables.tf new file mode 100644 index 0000000000..314d243125 --- /dev/null +++ b/modules/dataproc/variables.tf @@ -0,0 +1,240 @@ +/** + * 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. + */ + +variable "dataproc_config" { + description = "Dataproc cluster config." + type = object({ + graceful_decommission_timeout = optional(string, null) + cluster_config = optional(object({ + staging_bucket = optional(string, null) + temp_bucket = optional(string, null) + gce_cluster_config = optional(object({ + zone = optional(string, null) + network = optional(string, null) + subnetwork = optional(string, null) + service_account = optional(string, null) + service_account_scopes = optional(list(string), null) + tags = optional(list(string), []) + internal_ip_only = optional(bool, null) + metadata = optional(map(string), {}) + reservation_affinity = optional(object({ + consume_reservation_type = string + key = string + values = string + }), null) + node_group_affinity = optional(object({ + node_group_uri = string + }), null) + + shielded_instance_config = optional(object({ + enable_secure_boot = bool + enable_vtpm = bool + enable_integrity_monitoring = bool + }), null) + }), null) + master_config = optional(object({ + num_instances = number + machine_type = string + min_cpu_platform = string + disk_config = optional(object({ + boot_disk_type = string + boot_disk_size_gb = number + num_local_ssds = number + }), null) + accelerators = optional(object({ + accelerator_type = string + accelerator_count = number + }), null) + }), null) + worker_config = optional(object({ + num_instances = number + machine_type = string + min_cpu_platform = string + disk_config = optional(object({ + boot_disk_type = string + boot_disk_size_gb = number + num_local_ssds = number + }), null) + image_uri = string + accelerators = optional(object({ + accelerator_type = string + accelerator_count = number + }), null) + }), null) + preemptible_worker_config = optional(object({ + num_instances = number + preemptibility = string + disk_config = optional(object({ + boot_disk_type = string + boot_disk_size_gb = number + num_local_ssds = number + }), null) + }), null) + software_config = optional(object({ + image_version = optional(string, null) + override_properties = map(string) + optional_components = optional(list(string), null) + }), null) + security_config = optional(object({ + kerberos_config = object({ + cross_realm_trust_admin_server = optional(string, null) + cross_realm_trust_kdc = optional(string, null) + cross_realm_trust_realm = optional(string, null) + cross_realm_trust_shared_password_uri = optional(string, null) + enable_kerberos = optional(string, null) + kdc_db_key_uri = optional(string, null) + key_password_uri = optional(string, null) + keystore_uri = optional(string, null) + keystore_password_uri = optional(string, null) + kms_key_uri = string + realm = optional(string, null) + root_principal_password_uri = string + tgt_lifetime_hours = optional(string, null) + truststore_password_uri = optional(string, null) + truststore_uri = optional(string, null) + }) + }), null) + autoscaling_config = optional(object({ + policy_uri = string + }), null) + initialization_action = optional(object({ + script = string + timeout_sec = optional(string, null) + }), null) + encryption_config = optional(object({ + kms_key_name = string + }), null) + lifecycle_config = optional(object({ + idle_delete_ttl = optional(string, null) + auto_delete_time = optional(string, null) + }), null) + endpoint_config = optional(object({ + enable_http_port_access = string + }), null) + dataproc_metric_config = optional(object({ + metrics = list(object({ + metric_source = string + metric_overrides = optional(string, null) + })) + }), null) + metastore_config = optional(object({ + dataproc_metastore_service = string + }), null) + }), null) + + virtual_cluster_config = optional(object({ + staging_bucket = optional(string, null) + auxiliary_services_config = optional(object({ + metastore_config = optional(object({ + dataproc_metastore_service = string + }), null) + spark_history_server_config = optional(object({ + dataproc_cluster = string + }), null) + }), null) + kubernetes_cluster_config = object({ + kubernetes_namespace = optional(string, null) + kubernetes_software_config = object({ + component_version = list(map(string)) + properties = optional(list(map(string)), null) + }) + + gke_cluster_config = object({ + gke_cluster_target = optional(string, null) + node_pool_target = optional(object({ + node_pool = string + roles = list(string) + node_pool_config = optional(object({ + autoscaling = optional(object({ + min_node_count = optional(number, null) + max_node_count = optional(number, null) + }), null) + + config = object({ + machine_type = optional(string, null) + preemptible = optional(bool, null) + local_ssd_count = optional(number, null) + min_cpu_platform = optional(string, null) + spot = optional(bool, null) + }) + + locations = optional(list(string), null) + }), null) + }), null) + }) + }) + }), null) + }) + default = {} +} + +variable "group_iam" { + description = "Authoritative IAM binding for organization groups, in {GROUP_EMAIL => [ROLES]} format. Group emails need to be static. Can be used in combination with the `iam` variable." + type = map(list(string)) + default = {} + nullable = false +} + +variable "iam" { + description = "IAM bindings in {ROLE => [MEMBERS]} format." + type = map(list(string)) + default = {} + nullable = false +} + +variable "iam_additive" { + description = "IAM additive bindings in {ROLE => [MEMBERS]} format." + type = map(list(string)) + default = {} + nullable = false +} + +variable "labels" { + description = "The resource labels for instance to use to annotate any related underlying resources, such as Compute Engine VMs." + type = map(string) + default = {} +} + +variable "name" { + description = "Cluster name." + type = string +} + +variable "prefix" { + description = "Optional prefix used to generate project id and name." + type = string + default = null + validation { + condition = var.prefix != "" + error_message = "Prefix cannot be empty, please use null instead." + } +} + +variable "project_id" { + description = "Project ID." + type = string +} + +variable "region" { + description = "Dataproc region." + type = string +} + +variable "service_account" { + description = "Service account to set on the Dataproc cluster." + type = string + default = null +} diff --git a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/versions.tf b/modules/dataproc/versions.tf similarity index 91% rename from blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/versions.tf rename to modules/dataproc/versions.tf index 08492c6f95..cef924ea40 100644 --- a/blueprints/cloud-operations/terraform-enterprise-wif/tfc-workflow-using-wif/tfc-oidc/versions.tf +++ b/modules/dataproc/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/dns/versions.tf b/modules/dns/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/dns/versions.tf +++ b/modules/dns/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/endpoints/versions.tf b/modules/endpoints/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/endpoints/versions.tf +++ b/modules/endpoints/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/folder/README.md b/modules/folder/README.md index e1ad6809e2..8addd48ef2 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -42,40 +42,46 @@ module "folder" { name = "Folder name" org_policies = { "compute.disableGuestAttributesAccess" = { - enforce = true + rules = [{ enforce = true }] } - "constraints/compute.skipDefaultNetworkCreation" = { - enforce = true + "compute.skipDefaultNetworkCreation" = { + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyCreation" = { - enforce = true + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyUpload" = { - enforce = false rules = [ { condition = { - expression = "resource.matchTagId(\"tagKeys/1234\", \"tagValues/1234\")" + expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')" title = "condition" description = "test condition" location = "somewhere" } enforce = true + }, + { + enforce = false } ] } - "constraints/iam.allowedPolicyMemberDomains" = { - allow = { - values = ["C0xxxxxxx", "C0yyyyyyy"] - } + "iam.allowedPolicyMemberDomains" = { + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] } - "constraints/compute.trustedImageProjects" = { - allow = { - values = ["projects/my-project"] - } + "compute.trustedImageProjects" = { + rules = [{ + allow = { + values = ["projects/my-project"] + } + }] } - "constraints/compute.vmExternalIpAccess" = { - deny = { all = true } + "compute.vmExternalIpAccess" = { + rules = [{ deny = { all = true } }] } } } @@ -340,10 +346,10 @@ module "folder" { | [logging_exclusions](variables.tf#L98) | Logging exclusions for this folder in the form {NAME -> FILTER}. | map(string) | | {} | | [logging_sinks](variables.tf#L105) | Logging sinks to create for the organization. | map(object({…})) | | {} | | [name](variables.tf#L135) | Folder name. | string | | null | -| [org_policies](variables.tf#L141) | Organization policies applied to this folder keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L181) | Path containing org policies in YAML format. | string | | null | -| [parent](variables.tf#L187) | Parent in folders/folder_id or organizations/org_id format. | string | | null | -| [tag_bindings](variables.tf#L197) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null | +| [org_policies](variables.tf#L141) | Organization policies applied to this folder keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L168) | Path containing org policies in YAML format. | string | | null | +| [parent](variables.tf#L174) | Parent in folders/folder_id or organizations/org_id format. | string | | null | +| [tag_bindings](variables.tf#L184) | Tag bindings for this folder, in key => tag value id format. | map(string) | | null | ## Outputs diff --git a/modules/folder/organization-policies.tf b/modules/folder/organization-policies.tf index 47532f21be..2bf79c4ab6 100644 --- a/modules/folder/organization-policies.tf +++ b/modules/folder/organization-policies.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -28,16 +28,6 @@ locals { k => { inherit_from_parent = try(v.inherit_from_parent, null) reset = try(v.reset, null) - allow = can(v.allow) ? { - all = try(v.allow.all, null) - values = try(v.allow.values, null) - } : null - deny = can(v.deny) ? { - all = try(v.deny.all, null) - values = try(v.deny.values, null) - } : null - enforce = try(v.enforce, true) - rules = [ for r in try(v.rules, []) : { allow = can(r.allow) ? { @@ -48,7 +38,7 @@ locals { all = try(r.deny.all, null) values = try(r.deny.values, null) } : null - enforce = try(r.enforce, true) + enforce = try(r.enforce, null) condition = { description = try(r.condition.description, null) expression = try(r.condition.expression, null) @@ -67,8 +57,9 @@ locals { k => merge(v, { name = "${local.folder.name}/policies/${k}" parent = local.folder.name - - is_boolean_policy = v.allow == null && v.deny == null + is_boolean_policy = ( + alltrue([for r in v.rules : r.allow == null && r.deny == null]) + ) has_values = ( length(coalesce(try(v.allow.values, []), [])) > 0 || length(coalesce(try(v.deny.values, []), [])) > 0 @@ -90,11 +81,9 @@ resource "google_org_policy_policy" "default" { for_each = local.org_policies name = each.value.name parent = each.value.parent - spec { inherit_from_parent = each.value.inherit_from_parent reset = each.value.reset - dynamic "rules" { for_each = each.value.rules iterator = rule @@ -106,11 +95,14 @@ resource "google_org_policy_policy" "default" { ? upper(tostring(rule.value.enforce)) : null ) - condition { - description = rule.value.condition.description - expression = rule.value.condition.expression - location = rule.value.condition.location - title = rule.value.condition.title + dynamic "condition" { + for_each = rule.value.condition.expression != null ? [1] : [] + content { + description = rule.value.condition.description + expression = rule.value.condition.expression + location = rule.value.condition.location + title = rule.value.condition.title + } } dynamic "values" { for_each = rule.value.has_values ? [1] : [] @@ -121,22 +113,5 @@ resource "google_org_policy_policy" "default" { } } } - - rules { - allow_all = try(each.value.allow.all, null) == true ? "TRUE" : null - deny_all = try(each.value.deny.all, null) == true ? "TRUE" : null - enforce = ( - each.value.is_boolean_policy && each.value.enforce != null - ? upper(tostring(each.value.enforce)) - : null - ) - dynamic "values" { - for_each = each.value.has_values ? [1] : [] - content { - allowed_values = try(each.value.allow.values, null) - denied_values = try(each.value.deny.values, null) - } - } - } } } diff --git a/modules/folder/variables.tf b/modules/folder/variables.tf index a93ea1aae9..e0abc612c1 100644 --- a/modules/folder/variables.tf +++ b/modules/folder/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -143,19 +143,6 @@ variable "org_policies" { type = map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) - - # default (unconditional) values - allow = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - deny = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - enforce = optional(bool, true) # for boolean policies only. - - # conditional values rules = optional(list(object({ allow = optional(object({ all = optional(bool) @@ -165,13 +152,13 @@ variable "org_policies" { all = optional(bool) values = optional(list(string)) })) - enforce = optional(bool, true) # for boolean policies only. - condition = object({ + enforce = optional(bool) # for boolean policies only. + condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) - }) + }), {}) })), []) })) default = {} diff --git a/modules/folder/versions.tf b/modules/folder/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/folder/versions.tf +++ b/modules/folder/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/gcs/versions.tf b/modules/gcs/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/gcs/versions.tf +++ b/modules/gcs/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/gke-cluster/README.md b/modules/gke-cluster/README.md index 2e09aeb113..2d60e487c4 100644 --- a/modules/gke-cluster/README.md +++ b/modules/gke-cluster/README.md @@ -91,8 +91,7 @@ module "cluster-autopilot" { master_ipv4_cidr_block = "192.168.0.0/28" } enable_features = { - autopilot = true - workload_identity = false + autopilot = true } } # tftest modules=1 resources=1 inventory=autopilot.yaml @@ -162,5 +161,6 @@ module "cluster-1" { | [name](outputs.tf#L49) | Cluster name. | | | [notifications](outputs.tf#L54) | GKE PubSub notifications topic. | | | [self_link](outputs.tf#L59) | Cluster self link. | ✓ | +| [workload_identity_pool](outputs.tf#L65) | Workload identity pool. | | diff --git a/modules/gke-cluster/main.tf b/modules/gke-cluster/main.tf index 0079dd8d88..107d8341cf 100644 --- a/modules/gke-cluster/main.tf +++ b/modules/gke-cluster/main.tf @@ -379,7 +379,7 @@ resource "google_container_cluster" "cluster" { } dynamic "workload_identity_config" { - for_each = var.enable_features.workload_identity ? [""] : [] + for_each = (var.enable_features.workload_identity && !var.enable_features.autopilot) ? [""] : [] content { workload_pool = "${var.project_id}.svc.id.goog" } diff --git a/modules/gke-cluster/outputs.tf b/modules/gke-cluster/outputs.tf index f98f4f54c7..c02c9be2b6 100644 --- a/modules/gke-cluster/outputs.tf +++ b/modules/gke-cluster/outputs.tf @@ -61,3 +61,11 @@ output "self_link" { sensitive = true value = google_container_cluster.cluster.self_link } + +output "workload_identity_pool" { + description = "Workload identity pool." + value = "${var.project_id}.svc.id.goog" + depends_on = [ + google_container_cluster.cluster + ] +} \ No newline at end of file diff --git a/modules/gke-cluster/versions.tf b/modules/gke-cluster/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/gke-cluster/versions.tf +++ b/modules/gke-cluster/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/gke-hub/README.md b/modules/gke-hub/README.md index 793a81cacd..ed80af5590 100644 --- a/modules/gke-hub/README.md +++ b/modules/gke-hub/README.md @@ -314,7 +314,7 @@ module "hub" { ] } -# tftest modules=8 resources=31 +# tftest modules=8 resources=32 ``` diff --git a/modules/gke-hub/main.tf b/modules/gke-hub/main.tf index ddd35a4627..cf65f4c10a 100644 --- a/modules/gke-hub/main.tf +++ b/modules/gke-hub/main.tf @@ -41,12 +41,12 @@ resource "google_gke_hub_membership" "default" { membership_id = each.key endpoint { gke_cluster { - resource_link = each.value + resource_link = "//container.googleapis.com/${each.value}" } } dynamic "authority" { for_each = ( - contains(var.workload_identity_clusters, each.key) ? {} : { 1 = 1 } + contains(var.workload_identity_clusters, each.key) ? { 1 = 1 } : {} ) content { issuer = "https://container.googleapis.com/v1/${var.clusters[each.key]}" diff --git a/modules/gke-hub/versions.tf b/modules/gke-hub/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/gke-hub/versions.tf +++ b/modules/gke-hub/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/gke-nodepool/main.tf b/modules/gke-nodepool/main.tf index ad0c053f35..9ae4cf2844 100644 --- a/modules/gke-nodepool/main.tf +++ b/modules/gke-nodepool/main.tf @@ -115,9 +115,9 @@ resource "google_container_node_pool" "nodepool" { dynamic "network_config" { for_each = var.pod_range != null ? [""] : [] content { - create_pod_range = var.pod_range.create - pod_ipv4_cidr_block = var.pod_range.cidr - pod_range = var.pod_range.name + create_pod_range = var.pod_range.secondary_pod_range.create + pod_ipv4_cidr_block = var.pod_range.secondary_pod_range.cidr + pod_range = var.pod_range.secondary_pod_range.name } } diff --git a/modules/gke-nodepool/versions.tf b/modules/gke-nodepool/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/gke-nodepool/versions.tf +++ b/modules/gke-nodepool/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/iam-service-account/versions.tf b/modules/iam-service-account/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/iam-service-account/versions.tf +++ b/modules/iam-service-account/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/kms/versions.tf b/modules/kms/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/kms/versions.tf +++ b/modules/kms/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/logging-bucket/versions.tf b/modules/logging-bucket/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/logging-bucket/versions.tf +++ b/modules/logging-bucket/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-address/versions.tf b/modules/net-address/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-address/versions.tf +++ b/modules/net-address/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-cloudnat/versions.tf b/modules/net-cloudnat/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-cloudnat/versions.tf +++ b/modules/net-cloudnat/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-glb/versions.tf b/modules/net-glb/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-glb/versions.tf +++ b/modules/net-glb/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-ilb-l7/README.md b/modules/net-ilb-l7/README.md index b5862f31e6..b6436e92d5 100644 --- a/modules/net-ilb-l7/README.md +++ b/modules/net-ilb-l7/README.md @@ -326,8 +326,10 @@ module "ilb-l7" { group = "my-neg" max_rate = { per_endpoint = 1 } }] + health_checks = [] } } + health_check_configs = {} neg_configs = { my-neg = { cloudrun = { @@ -343,7 +345,7 @@ module "ilb-l7" { subnetwork = var.subnet.self_link } } -# tftest modules=1 resources=6 +# tftest modules=1 resources=5 ``` ### URL Map diff --git a/modules/net-ilb-l7/backend-service.tf b/modules/net-ilb-l7/backend-service.tf index a517bd08c8..ea758835bd 100644 --- a/modules/net-ilb-l7/backend-service.tf +++ b/modules/net-ilb-l7/backend-service.tf @@ -46,7 +46,7 @@ resource "google_compute_region_backend_service" "default" { description = var.description affinity_cookie_ttl_sec = each.value.affinity_cookie_ttl_sec connection_draining_timeout_sec = each.value.connection_draining_timeout_sec - health_checks = [ + health_checks = length(each.value.health_checks) == 0 ? null : [ for k in each.value.health_checks : lookup(local.hc_ids, k, k) ] # not for internet / serverless NEGs locality_lb_policy = each.value.locality_lb_policy diff --git a/modules/net-ilb-l7/versions.tf b/modules/net-ilb-l7/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-ilb-l7/versions.tf +++ b/modules/net-ilb-l7/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-ilb/health-check.tf b/modules/net-ilb/health-check.tf index 4a4ed40def..88f9f6ea73 100644 --- a/modules/net-ilb/health-check.tf +++ b/modules/net-ilb/health-check.tf @@ -76,13 +76,13 @@ resource "google_compute_health_check" "default" { dynamic "https_health_check" { for_each = local.hc_https ? [""] : [] content { - host = local.hc.http.host - port = local.hc.http.port - port_name = local.hc.http.port_name - port_specification = local.hc.http.port_specification - proxy_header = local.hc.http.proxy_header - request_path = local.hc.http.request_path - response = local.hc.http.response + host = local.hc.https.host + port = local.hc.https.port + port_name = local.hc.https.port_name + port_specification = local.hc.https.port_specification + proxy_header = local.hc.https.proxy_header + request_path = local.hc.https.request_path + response = local.hc.https.response } } diff --git a/modules/net-ilb/versions.tf b/modules/net-ilb/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-ilb/versions.tf +++ b/modules/net-ilb/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-interconnect-attachment-direct/versions.tf b/modules/net-interconnect-attachment-direct/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-interconnect-attachment-direct/versions.tf +++ b/modules/net-interconnect-attachment-direct/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-vpc-firewall/versions.tf b/modules/net-vpc-firewall/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-vpc-firewall/versions.tf +++ b/modules/net-vpc-firewall/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-vpc-peering/versions.tf b/modules/net-vpc-peering/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-vpc-peering/versions.tf +++ b/modules/net-vpc-peering/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-vpc/README.md b/modules/net-vpc/README.md index dbd8550221..25dfaa58fd 100644 --- a/modules/net-vpc/README.md +++ b/modules/net-vpc/README.md @@ -174,7 +174,7 @@ module "vpc-host" { ip_cidr_range = "10.0.0.0/24" name = "subnet-1" region = "europe-west1" - secondary_ip_range = { + secondary_ip_ranges = { pods = "172.16.0.0/20" services = "192.168.0.0/24" } @@ -314,7 +314,7 @@ module "vpc" { name = "my-network" data_folder = "config/subnets" } -# tftest modules=1 resources=3 files=subnet-simple,subnet-detailed inventory=factory.yaml +# tftest modules=1 resources=4 files=subnet-simple,subnet-detailed inventory=factory.yaml ``` ```yaml diff --git a/modules/net-vpc/subnets.tf b/modules/net-vpc/subnets.tf index ae094ecfa0..7c03bfca3b 100644 --- a/modules/net-vpc/subnets.tf +++ b/modules/net-vpc/subnets.tf @@ -31,6 +31,9 @@ locals { flow_logs_config = try(v.flow_logs, null) ipv6 = try(v.ipv6, null) secondary_ip_ranges = try(v.secondary_ip_ranges, null) + iam_groups = try(v.iam_groups, []) + iam_users = try(v.iam_users, []) + iam_service_accounts = try(v.iam_service_accounts, []) } } _factory_subnets_iam = [ diff --git a/modules/net-vpc/versions.tf b/modules/net-vpc/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-vpc/versions.tf +++ b/modules/net-vpc/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-vpn-dynamic/versions.tf b/modules/net-vpn-dynamic/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-vpn-dynamic/versions.tf +++ b/modules/net-vpn-dynamic/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-vpn-ha/README.md b/modules/net-vpn-ha/README.md index 0b7b52903a..8bbac84d5d 100644 --- a/modules/net-vpn-ha/README.md +++ b/modules/net-vpn-ha/README.md @@ -1,17 +1,21 @@ # Cloud HA VPN Module + This module makes it easy to deploy either GCP-to-GCP or GCP-to-On-prem [Cloud HA VPN](https://cloud.google.com/vpn/docs/concepts/overview#ha-vpn). ## Examples ### GCP to GCP + ```hcl module "vpn-1" { - source = "./fabric/modules/net-vpn-ha" - project_id = var.project_id - region = "europe-west4" - network = var.vpc1.self_link - name = "net1-to-net-2" - peer_gateway = { gcp = module.vpn-2.self_link } + source = "./fabric/modules/net-vpn-ha" + project_id = var.project_id + region = "europe-west4" + network = var.vpc1.self_link + name = "net1-to-net-2" + peer_gateways = { + default = { gcp = module.vpn-2.self_link } + } router_config = { asn = 64514 custom_advertise = { @@ -48,7 +52,9 @@ module "vpn-2" { network = var.vpc2.self_link name = "net2-to-net1" router_config = { asn = 64513 } - peer_gateway = { gcp = module.vpn-1.self_link } + peer_gateways = { + default = { gcp = module.vpn-1.self_link } + } tunnels = { remote-0 = { bgp_peer = { @@ -84,10 +90,12 @@ module "vpn_ha" { region = var.region network = var.vpc.self_link name = "mynet-to-onprem" - peer_gateway = { - external = { - redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" - interfaces = ["8.8.8.8"] # on-prem router ip address + peer_gateways = { + default = { + external = { + redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT" + interfaces = ["8.8.8.8"] # on-prem router ip address + } } } router_config = { asn = 64514 } @@ -124,13 +132,13 @@ module "vpn_ha" { |---|---|:---:|:---:|:---:| | [name](variables.tf#L17) | VPN Gateway name (if an existing VPN Gateway is not used), and prefix used for dependent resources. | string | ✓ | | | [network](variables.tf#L22) | VPC used for the gateway and routes. | string | ✓ | | -| [peer_gateway](variables.tf#L27) | Configuration of the (external or GCP) peer gateway. | object({…}) | ✓ | | -| [project_id](variables.tf#L43) | Project where resources will be created. | string | ✓ | | -| [region](variables.tf#L48) | Region used for resources. | string | ✓ | | -| [router_config](variables.tf#L53) | Cloud Router configuration for the VPN. If you want to reuse an existing router, set create to false and use name to specify the desired router. | object({…}) | ✓ | | -| [tunnels](variables.tf#L68) | VPN tunnel configurations. | map(object({…})) | | {} | -| [vpn_gateway](variables.tf#L95) | HA VPN Gateway Self Link for using an existing HA VPN Gateway. Ignored if `vpn_gateway_create` is set to `true`. | string | | null | -| [vpn_gateway_create](variables.tf#L101) | Create HA VPN Gateway. | bool | | true | +| [project_id](variables.tf#L46) | Project where resources will be created. | string | ✓ | | +| [region](variables.tf#L51) | Region used for resources. | string | ✓ | | +| [router_config](variables.tf#L56) | Cloud Router configuration for the VPN. If you want to reuse an existing router, set create to false and use name to specify the desired router. | object({…}) | ✓ | | +| [peer_gateways](variables.tf#L27) | Configuration of the (external or GCP) peer gateway. | map(object({…})) | | {} | +| [tunnels](variables.tf#L71) | VPN tunnel configurations. | map(object({…})) | | {} | +| [vpn_gateway](variables.tf#L99) | HA VPN Gateway Self Link for using an existing HA VPN Gateway. Ignored if `vpn_gateway_create` is set to `true`. | string | | null | +| [vpn_gateway_create](variables.tf#L105) | Create HA VPN Gateway. | bool | | true | ## Outputs diff --git a/modules/net-vpn-ha/main.tf b/modules/net-vpn-ha/main.tf index 9d53ee080c..31bc0ddc9b 100644 --- a/modules/net-vpn-ha/main.tf +++ b/modules/net-vpn-ha/main.tf @@ -16,6 +16,12 @@ */ locals { + peer_gateways_external = { + for k, v in var.peer_gateways : k => v.external if v.external != null + } + peer_gateways_gcp = { + for k, v in var.peer_gateways : k => v.gcp if v.gcp != null + } router = ( var.router_config.create ? try(google_compute_router.router[0].name, null) @@ -38,13 +44,13 @@ resource "google_compute_ha_vpn_gateway" "ha_gateway" { } resource "google_compute_external_vpn_gateway" "external_gateway" { - count = var.peer_gateway.external != null ? 1 : 0 - name = "external-${var.name}" + for_each = local.peer_gateways_external + name = "${var.name}-${each.key}" project = var.project_id - redundancy_type = var.peer_gateway.external.redundancy_type + redundancy_type = each.value.redundancy_type description = "Terraform managed external VPN gateway" dynamic "interface" { - for_each = var.peer_gateway.external.interfaces + for_each = each.value.interfaces content { id = interface.key ip_address = interface.value @@ -124,18 +130,23 @@ resource "google_compute_router_interface" "router_interface" { } resource "google_compute_vpn_tunnel" "tunnels" { - for_each = var.tunnels - project = var.project_id - region = var.region - name = "${var.name}-${each.key}" - router = local.router - peer_external_gateway = one(google_compute_external_vpn_gateway.external_gateway[*].self_link) + for_each = var.tunnels + project = var.project_id + region = var.region + name = "${var.name}-${each.key}" + router = local.router + peer_external_gateway = try( + google_compute_external_vpn_gateway.external_gateway[each.value.peer_gateway].id, + null + ) peer_external_gateway_interface = each.value.peer_external_gateway_interface - peer_gcp_gateway = var.peer_gateway.gcp - vpn_gateway_interface = each.value.vpn_gateway_interface - ike_version = each.value.ike_version - shared_secret = coalesce(each.value.shared_secret, local.secret) - vpn_gateway = local.vpn_gateway + peer_gcp_gateway = lookup( + local.peer_gateways_gcp, each.value.peer_gateway, null + ) + vpn_gateway_interface = each.value.vpn_gateway_interface + ike_version = each.value.ike_version + shared_secret = coalesce(each.value.shared_secret, local.secret) + vpn_gateway = local.vpn_gateway } resource "random_id" "secret" { diff --git a/modules/net-vpn-ha/variables.tf b/modules/net-vpn-ha/variables.tf index a423eab155..b12c4cdca1 100644 --- a/modules/net-vpn-ha/variables.tf +++ b/modules/net-vpn-ha/variables.tf @@ -24,18 +24,21 @@ variable "network" { type = string } -variable "peer_gateway" { +variable "peer_gateways" { description = "Configuration of the (external or GCP) peer gateway." - type = object({ + type = map(object({ external = optional(object({ redundancy_type = string interfaces = list(string) })) gcp = optional(string) - }) + })) nullable = false + default = {} validation { - condition = (var.peer_gateway.external != null) != (var.peer_gateway.gcp != null) + condition = alltrue([ + for k, v in var.peer_gateways : (v.external != null) != (v.gcp != null) + ]) error_message = "Peer gateway configuration must define exactly one between `external` and `gcp`." } } @@ -84,6 +87,7 @@ variable "tunnels" { bgp_session_range = string ike_version = optional(number, 2) peer_external_gateway_interface = optional(number) + peer_gateway = optional(string, "default") router = optional(string) shared_secret = optional(string) vpn_gateway_interface = number diff --git a/modules/net-vpn-ha/versions.tf b/modules/net-vpn-ha/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-vpn-ha/versions.tf +++ b/modules/net-vpn-ha/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/net-vpn-static/versions.tf b/modules/net-vpn-static/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/net-vpn-static/versions.tf +++ b/modules/net-vpn-static/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/organization/README.md b/modules/organization/README.md index b6caa3cd03..39b5ff29e7 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -25,50 +25,77 @@ module "org" { iam_additive_members = { "user:compute@example.org" = ["roles/compute.admin", "roles/container.viewer"] } - + tags = { + allowexternal = { + description = "Allow external identities." + values = { + true = {}, false = {} + } + } + } org_policies = { "custom.gkeEnableAutoUpgrade" = { - enforce = true + rules = [{ enforce = true }] } "compute.disableGuestAttributesAccess" = { - enforce = true + rules = [{ enforce = true }] } - "constraints/compute.skipDefaultNetworkCreation" = { - enforce = true + "compute.skipDefaultNetworkCreation" = { + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyCreation" = { - enforce = true + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyUpload" = { - enforce = false rules = [ { condition = { - expression = "resource.matchTagId(\"tagKeys/1234\", \"tagValues/1234\")" + expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')" title = "condition" description = "test condition" location = "somewhere" } enforce = true + }, + { + enforce = false } ] } - "constraints/iam.allowedPolicyMemberDomains" = { - allow = { - values = ["C0xxxxxxx", "C0yyyyyyy"] - } + "iam.allowedPolicyMemberDomains" = { + rules = [ + { + allow = { all = true } + condition = { + expression = "resource.matchTag('1234567890/allowexternal', 'true')" + title = "Allow external identities" + description = "Allow external identities when resource has the `allowexternal` tag set to true." + } + }, + { + allow = { values = ["C0xxxxxxx", "C0yyyyyyy"] } + condition = { + expression = "!resource.matchTag('1234567890/allowexternal', 'true')" + title = "" + description = "For any resource without allowexternal=true, only allow identities from restricted domains." + } + } + ] } - "constraints/compute.trustedImageProjects" = { - allow = { - values = ["projects/my-project"] - } + + "compute.trustedImageProjects" = { + rules = [{ + allow = { + values = ["projects/my-project"] + } + }] } - "constraints/compute.vmExternalIpAccess" = { - deny = { all = true } + "compute.vmExternalIpAccess" = { + rules = [{ deny = { all = true } }] } } } -# tftest modules=1 resources=13 inventory=basic.yaml +# tftest modules=1 resources=16 inventory=basic.yaml ``` ## IAM @@ -111,7 +138,7 @@ module "org" { # not necessarily to enforce on the org level, policy may be applied on folder/project levels org_policies = { "custom.gkeEnableAutoUpgrade" = { - enforce = true + rules = [{ enforce = true }] } } } @@ -131,7 +158,7 @@ module "org" { org_policy_custom_constraints_data_path = "configs/custom-constraints" org_policies = { "custom.gkeEnableAutoUpgrade" = { - enforce = true + rules = [{ enforce = true }] } } } @@ -447,7 +474,7 @@ module "org" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [organization_id](variables.tf#L246) | Organization id in organizations/nnnnnn format. | string | ✓ | | +| [organization_id](variables.tf#L234) | Organization id in organizations/nnnnnn format. | string | ✓ | | | [contacts](variables.tf#L17) | List of essential contacts for this resource. Must be in the form EMAIL -> [NOTIFICATION_TYPES]. Valid notification types are ALL, SUSPENSION, SECURITY, TECHNICAL, BILLING, LEGAL, PRODUCT_UPDATES. | map(list(string)) | | {} | | [custom_roles](variables.tf#L24) | Map of role name => list of permissions to create in this project. | map(list(string)) | | {} | | [firewall_policies](variables.tf#L31) | Hierarchical firewall policy rules created in the organization. | map(map(object({…}))) | | {} | @@ -463,12 +490,12 @@ module "org" { | [logging_exclusions](variables.tf#L122) | Logging exclusions for this organization in the form {NAME -> FILTER}. | map(string) | | {} | | [logging_sinks](variables.tf#L129) | Logging sinks to create for the organization. | map(object({…})) | | {} | | [network_tags](variables.tf#L159) | Network tags by key name. If `id` is provided, key creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | -| [org_policies](variables.tf#L181) | Organization policies applied to this organization keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L220) | Path containing org policies in YAML format. | string | | null | -| [org_policy_custom_constraints](variables.tf#L226) | Organization policiy custom constraints keyed by constraint name. | map(object({…})) | | {} | -| [org_policy_custom_constraints_data_path](variables.tf#L240) | Path containing org policy custom constraints in YAML format. | string | | null | -| [tag_bindings](variables.tf#L255) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null | -| [tags](variables.tf#L261) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | +| [org_policies](variables.tf#L181) | Organization policies applied to this organization keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L208) | Path containing org policies in YAML format. | string | | null | +| [org_policy_custom_constraints](variables.tf#L214) | Organization policiy custom constraints keyed by constraint name. | map(object({…})) | | {} | +| [org_policy_custom_constraints_data_path](variables.tf#L228) | Path containing org policy custom constraints in YAML format. | string | | null | +| [tag_bindings](variables.tf#L243) | Tag bindings for this organization, in key => tag value id format. | map(string) | | null | +| [tags](variables.tf#L249) | Tags by key name. If `id` is provided, key or value creation is skipped. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | ## Outputs diff --git a/modules/organization/organization-policies.tf b/modules/organization/organization-policies.tf index 1a99ef9a1c..b43c5955c6 100644 --- a/modules/organization/organization-policies.tf +++ b/modules/organization/organization-policies.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -28,16 +28,6 @@ locals { k => { inherit_from_parent = try(v.inherit_from_parent, null) reset = try(v.reset, null) - allow = can(v.allow) ? { - all = try(v.allow.all, null) - values = try(v.allow.values, null) - } : null - deny = can(v.deny) ? { - all = try(v.deny.all, null) - values = try(v.deny.values, null) - } : null - enforce = try(v.enforce, true) - rules = [ for r in try(v.rules, []) : { allow = can(r.allow) ? { @@ -48,7 +38,7 @@ locals { all = try(r.deny.all, null) values = try(r.deny.values, null) } : null - enforce = try(r.enforce, true) + enforce = try(r.enforce, null) condition = { description = try(r.condition.description, null) expression = try(r.condition.expression, null) @@ -67,8 +57,9 @@ locals { k => merge(v, { name = "${var.organization_id}/policies/${k}" parent = var.organization_id - - is_boolean_policy = v.allow == null && v.deny == null + is_boolean_policy = ( + alltrue([for r in v.rules : r.allow == null && r.deny == null]) + ) has_values = ( length(coalesce(try(v.allow.values, []), [])) > 0 || length(coalesce(try(v.deny.values, []), [])) > 0 @@ -90,11 +81,9 @@ resource "google_org_policy_policy" "default" { for_each = local.org_policies name = each.value.name parent = each.value.parent - spec { inherit_from_parent = each.value.inherit_from_parent reset = each.value.reset - dynamic "rules" { for_each = each.value.rules iterator = rule @@ -106,11 +95,14 @@ resource "google_org_policy_policy" "default" { ? upper(tostring(rule.value.enforce)) : null ) - condition { - description = rule.value.condition.description - expression = rule.value.condition.expression - location = rule.value.condition.location - title = rule.value.condition.title + dynamic "condition" { + for_each = rule.value.condition.expression != null ? [1] : [] + content { + description = rule.value.condition.description + expression = rule.value.condition.expression + location = rule.value.condition.location + title = rule.value.condition.title + } } dynamic "values" { for_each = rule.value.has_values ? [1] : [] @@ -121,25 +113,7 @@ resource "google_org_policy_policy" "default" { } } } - - rules { - allow_all = try(each.value.allow.all, null) == true ? "TRUE" : null - deny_all = try(each.value.deny.all, null) == true ? "TRUE" : null - enforce = ( - each.value.is_boolean_policy && each.value.enforce != null - ? upper(tostring(each.value.enforce)) - : null - ) - dynamic "values" { - for_each = each.value.has_values ? [1] : [] - content { - allowed_values = try(each.value.allow.values, null) - denied_values = try(each.value.deny.values, null) - } - } - } } - depends_on = [ google_organization_iam_audit_config.config, google_organization_iam_binding.authoritative, diff --git a/modules/organization/variables.tf b/modules/organization/variables.tf index ced5cad3d2..619056a0af 100644 --- a/modules/organization/variables.tf +++ b/modules/organization/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -183,18 +183,6 @@ variable "org_policies" { type = map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) - - # default (unconditional) values - allow = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - deny = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - enforce = optional(bool, true) # for boolean policies only. - # conditional values rules = optional(list(object({ allow = optional(object({ all = optional(bool) @@ -204,13 +192,13 @@ variable "org_policies" { all = optional(bool) values = optional(list(string)) })) - enforce = optional(bool, true) # for boolean policies only. - condition = object({ + enforce = optional(bool) # for boolean policies only. + condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) - }) + }), {}) })), []) })) default = {} diff --git a/modules/organization/versions.tf b/modules/organization/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/organization/versions.tf +++ b/modules/organization/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/project/README.md b/modules/project/README.md index fbc4ab294d..7be0a1aa27 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -138,6 +138,29 @@ module "project" { # tftest modules=1 resources=2 ``` +### Using shortcodes for Service Identities in additive IAM +Most Service Identities contains project number in their e-mail address and this prevents additive IAM to work, as these values are not known at moment of execution of `terraform plan` (its not an issue for authoritative IAM). To refer current project Service Identities you may use shortcodes for Service Identities similarly as for `service_identity_iam` when configuring Shared VPC. + +```hcl +module "project" { + source = "./fabric/modules/project" + name = "project-example" + + services = [ + "run.googleapis.com", + "container.googleapis.com", + ] + + iam_additive = { + "roles/editor" = ["cloudservices"] + "roles/vpcaccess.user" = ["cloudrun"] + "roles/container.hostServiceAgentUser" = ["container-engine"] + } +} +# tftest modules=1 resources=6 +``` + + ### Service identities requiring manual IAM grants The module will create service identities at project creation instead of creating of them at the time of first use. This allows granting these service identities roles in other projects, something which is usually necessary in a Shared VPC context. @@ -166,6 +189,7 @@ This table lists all affected services and roles that you need to grant to servi | cloudasset.googleapis.com | cloudasset | roles/cloudasset.serviceAgent | | cloudbuild.googleapis.com | cloudbuild | roles/cloudbuild.builds.builder | | gkehub.googleapis.com | fleet | roles/gkehub.serviceAgent | +| meshconfig.googleapis.com | servicemesh | roles/anthosservicemesh.serviceAgent | | multiclusteringress.googleapis.com | multicluster-ingress | roles/multiclusteringress.serviceAgent | | pubsub.googleapis.com | pubsub | roles/pubsub.serviceAgent | | sqladmin.googleapis.com | sqladmin | roles/cloudsql.serviceAgent | @@ -190,7 +214,6 @@ module "service-project" { source = "./fabric/modules/project" name = "my-service-project" shared_vpc_service_config = { - attach = true host_project = module.host-project.project_id service_identity_iam = { "roles/compute.networkUser" = [ @@ -221,40 +244,46 @@ module "project" { prefix = "foo" org_policies = { "compute.disableGuestAttributesAccess" = { - enforce = true + rules = [{ enforce = true }] } - "constraints/compute.skipDefaultNetworkCreation" = { - enforce = true + "compute.skipDefaultNetworkCreation" = { + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyCreation" = { - enforce = true + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyUpload" = { - enforce = false rules = [ { condition = { - expression = "resource.matchTagId(\"tagKeys/1234\", \"tagValues/1234\")" + expression = "resource.matchTagId('tagKeys/1234', 'tagValues/1234')" title = "condition" description = "test condition" location = "somewhere" } enforce = true + }, + { + enforce = false } ] } - "constraints/iam.allowedPolicyMemberDomains" = { - allow = { - values = ["C0xxxxxxx", "C0yyyyyyy"] - } + "iam.allowedPolicyMemberDomains" = { + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] } - "constraints/compute.trustedImageProjects" = { - allow = { - values = ["projects/my-project"] - } + "compute.trustedImageProjects" = { + rules = [{ + allow = { + values = ["projects/my-project"] + } + }] } - "constraints/compute.vmExternalIpAccess" = { - deny = { all = true } + "compute.vmExternalIpAccess" = { + rules = [{ deny = { all = true } }] } } } @@ -284,36 +313,42 @@ module "project" { ```yaml # tftest-file id=boolean path=configs/org-policies/boolean.yaml compute.disableGuestAttributesAccess: - enforce: true -constraints/compute.skipDefaultNetworkCreation: - enforce: true + rules: + - enforce: true +compute.skipDefaultNetworkCreation: + rules: + - enforce: true iam.disableServiceAccountKeyCreation: - enforce: true + rules: + - enforce: true iam.disableServiceAccountKeyUpload: - enforce: false rules: - condition: description: test condition - expression: resource.matchTagId("tagKeys/1234", "tagValues/1234") + expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234') location: somewhere title: condition enforce: true + - enforce: false ``` ```yaml # tftest-file id=list path=configs/org-policies/list.yaml -constraints/compute.trustedImageProjects: - allow: - values: - - projects/my-project -constraints/compute.vmExternalIpAccess: - deny: - all: true -constraints/iam.allowedPolicyMemberDomains: - allow: - values: - - C0xxxxxxx - - C0yyyyyyy +compute.trustedImageProjects: + rules: + - allow: + values: + - projects/my-project +compute.vmExternalIpAccess: + rules: + - deny: + all: true +iam.allowedPolicyMemberDomains: + rules: + - allow: + values: + - C0xxxxxxx + - C0yyyyyyy ``` @@ -500,23 +535,23 @@ output "compute_robot" { | [logging_exclusions](variables.tf#L95) | Logging exclusions for this project in the form {NAME -> FILTER}. | map(string) | | {} | | [logging_sinks](variables.tf#L102) | Logging sinks to create for this project. | map(object({…})) | | {} | | [metric_scopes](variables.tf#L133) | List of projects that will act as metric scopes for this project. | list(string) | | [] | -| [org_policies](variables.tf#L145) | Organization policies applied to this project keyed by policy name. | map(object({…})) | | {} | -| [org_policies_data_path](variables.tf#L185) | Path containing org policies in YAML format. | string | | null | -| [oslogin](variables.tf#L191) | Enable OS Login. | bool | | false | -| [oslogin_admins](variables.tf#L197) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | list(string) | | [] | -| [oslogin_users](variables.tf#L205) | List of IAM-style identities that will be granted roles necessary for OS Login users. | list(string) | | [] | -| [parent](variables.tf#L212) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | | null | -| [prefix](variables.tf#L222) | Optional prefix used to generate project id and name. | string | | null | -| [project_create](variables.tf#L232) | Create project. When set to false, uses a data source to reference existing project. | bool | | true | -| [service_config](variables.tf#L238) | Configure service API activation. | object({…}) | | {…} | -| [service_encryption_key_ids](variables.tf#L250) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | map(list(string)) | | {} | -| [service_perimeter_bridges](variables.tf#L257) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | list(string) | | null | -| [service_perimeter_standard](variables.tf#L264) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | string | | null | -| [services](variables.tf#L270) | Service APIs to enable. | list(string) | | [] | -| [shared_vpc_host_config](variables.tf#L276) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…}) | | null | -| [shared_vpc_service_config](variables.tf#L285) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…}) | | null | -| [skip_delete](variables.tf#L295) | Allows the underlying resources to be destroyed without destroying the project itself. | bool | | false | -| [tag_bindings](variables.tf#L301) | Tag bindings for this project, in key => tag value id format. | map(string) | | null | +| [org_policies](variables.tf#L145) | Organization policies applied to this project keyed by policy name. | map(object({…})) | | {} | +| [org_policies_data_path](variables.tf#L172) | Path containing org policies in YAML format. | string | | null | +| [oslogin](variables.tf#L178) | Enable OS Login. | bool | | false | +| [oslogin_admins](variables.tf#L184) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | list(string) | | [] | +| [oslogin_users](variables.tf#L192) | List of IAM-style identities that will be granted roles necessary for OS Login users. | list(string) | | [] | +| [parent](variables.tf#L199) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | | null | +| [prefix](variables.tf#L209) | Optional prefix used to generate project id and name. | string | | null | +| [project_create](variables.tf#L219) | Create project. When set to false, uses a data source to reference existing project. | bool | | true | +| [service_config](variables.tf#L225) | Configure service API activation. | object({…}) | | {…} | +| [service_encryption_key_ids](variables.tf#L237) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | map(list(string)) | | {} | +| [service_perimeter_bridges](variables.tf#L244) | Name of VPC-SC Bridge perimeters to add project into. See comment in the variables file for format. | list(string) | | null | +| [service_perimeter_standard](variables.tf#L251) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | string | | null | +| [services](variables.tf#L257) | Service APIs to enable. | list(string) | | [] | +| [shared_vpc_host_config](variables.tf#L263) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…}) | | null | +| [shared_vpc_service_config](variables.tf#L272) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…}) | | null | +| [skip_delete](variables.tf#L282) | Allows the underlying resources to be destroyed without destroying the project itself. | bool | | false | +| [tag_bindings](variables.tf#L288) | Tag bindings for this project, in key => tag value id format. | map(string) | | null | ## Outputs diff --git a/modules/project/iam.tf b/modules/project/iam.tf index 69925cc767..3ed2d2a6fd 100644 --- a/modules/project/iam.tf +++ b/modules/project/iam.tf @@ -47,7 +47,18 @@ locals { } iam_additive = { for pair in concat(local._iam_additive_pairs, local._iam_additive_member_pairs) : - "${pair.role}-${pair.member}" => pair + "${pair.role}-${pair.member}" => { + role = pair.role + member = ( + pair.member == "cloudservices" + ? "serviceAccount:${local.service_account_cloud_services}" + : pair.member == "default-compute" + ? "serviceAccount:${local.service_accounts_default.compute}" + : pair.member == "default-gae" + ? "serviceAccount:${local.service_accounts_default.gae}" + : try("serviceAccount:${local.service_accounts_robots[pair.member]}", pair.member) + ) + } } } diff --git a/modules/project/organization-policies.tf b/modules/project/organization-policies.tf index 4ff5bb9922..37e6f2531f 100644 --- a/modules/project/organization-policies.tf +++ b/modules/project/organization-policies.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -28,16 +28,6 @@ locals { k => { inherit_from_parent = try(v.inherit_from_parent, null) reset = try(v.reset, null) - allow = can(v.allow) ? { - all = try(v.allow.all, null) - values = try(v.allow.values, null) - } : null - deny = can(v.deny) ? { - all = try(v.deny.all, null) - values = try(v.deny.values, null) - } : null - enforce = try(v.enforce, true) - rules = [ for r in try(v.rules, []) : { allow = can(r.allow) ? { @@ -48,7 +38,7 @@ locals { all = try(r.deny.all, null) values = try(r.deny.values, null) } : null - enforce = try(r.enforce, true) + enforce = try(r.enforce, null) condition = { description = try(r.condition.description, null) expression = try(r.condition.expression, null) @@ -67,8 +57,9 @@ locals { k => merge(v, { name = "projects/${local.project.project_id}/policies/${k}" parent = "projects/${local.project.project_id}" - - is_boolean_policy = v.allow == null && v.deny == null + is_boolean_policy = ( + alltrue([for r in v.rules : r.allow == null && r.deny == null]) + ) has_values = ( length(coalesce(try(v.allow.values, []), [])) > 0 || length(coalesce(try(v.deny.values, []), [])) > 0 @@ -90,11 +81,9 @@ resource "google_org_policy_policy" "default" { for_each = local.org_policies name = each.value.name parent = each.value.parent - spec { inherit_from_parent = each.value.inherit_from_parent reset = each.value.reset - dynamic "rules" { for_each = each.value.rules iterator = rule @@ -106,11 +95,14 @@ resource "google_org_policy_policy" "default" { ? upper(tostring(rule.value.enforce)) : null ) - condition { - description = rule.value.condition.description - expression = rule.value.condition.expression - location = rule.value.condition.location - title = rule.value.condition.title + dynamic "condition" { + for_each = rule.value.condition.expression != null ? [1] : [] + content { + description = rule.value.condition.description + expression = rule.value.condition.expression + location = rule.value.condition.location + title = rule.value.condition.title + } } dynamic "values" { for_each = rule.value.has_values ? [1] : [] @@ -121,22 +113,5 @@ resource "google_org_policy_policy" "default" { } } } - - rules { - allow_all = try(each.value.allow.all, null) == true ? "TRUE" : null - deny_all = try(each.value.deny.all, null) == true ? "TRUE" : null - enforce = ( - each.value.is_boolean_policy && each.value.enforce != null - ? upper(tostring(each.value.enforce)) - : null - ) - dynamic "values" { - for_each = each.value.has_values ? [1] : [] - content { - allowed_values = try(each.value.allow.values, null) - denied_values = try(each.value.deny.values, null) - } - } - } } } diff --git a/modules/project/service-accounts.tf b/modules/project/service-accounts.tf index e93978a860..96563ce062 100644 --- a/modules/project/service-accounts.tf +++ b/modules/project/service-accounts.tf @@ -50,6 +50,7 @@ locals { notebooks = "service-%s@gcp-sa-notebooks" pubsub = "service-%s@gcp-sa-pubsub" secretmanager = "service-%s@gcp-sa-secretmanager" + servicemesh = "service-%s@gcp-sa-servicemesh" sql = "service-%s@gcp-sa-cloud-sql" sqladmin = "service-%s@gcp-sa-cloud-sql" storage = "service-%s@gs-project-accounts" @@ -81,6 +82,7 @@ locals { "gkehub.googleapis.com", # grant roles/gkehub.serviceAgent to fleet "multiclusteringress.googleapis.com", # grant roles/multiclusteringress.serviceAgent to multicluster-ingress "pubsub.googleapis.com", # grant roles/pubsub.serviceAgent to pubsub + "meshconfig.googleapis.com", # grant roles/anthosservicemesh.serviceAgent to meshconfig "secretmanager.googleapis.com", # no grants needed "sqladmin.googleapis.com", # grant roles/cloudsql.serviceAgent to sqladmin (TODO: verify) ] diff --git a/modules/project/variables.tf b/modules/project/variables.tf index 3769a1fb4e..ede3a8c6ea 100644 --- a/modules/project/variables.tf +++ b/modules/project/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -147,19 +147,6 @@ variable "org_policies" { type = map(object({ inherit_from_parent = optional(bool) # for list policies only. reset = optional(bool) - - # default (unconditional) values - allow = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - deny = optional(object({ - all = optional(bool) - values = optional(list(string)) - })) - enforce = optional(bool, true) # for boolean policies only. - - # conditional values rules = optional(list(object({ allow = optional(object({ all = optional(bool) @@ -169,13 +156,13 @@ variable "org_policies" { all = optional(bool) values = optional(list(string)) })) - enforce = optional(bool, true) # for boolean policies only. - condition = object({ + enforce = optional(bool) # for boolean policies only. + condition = optional(object({ description = optional(string) expression = optional(string) location = optional(string) title = optional(string) - }) + }), {}) })), []) })) default = {} diff --git a/modules/project/versions.tf b/modules/project/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/project/versions.tf +++ b/modules/project/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/projects-data-source/README.md b/modules/projects-data-source/README.md index e48ac9770b..5d35f1ab0c 100644 --- a/modules/projects-data-source/README.md +++ b/modules/projects-data-source/README.md @@ -1,9 +1,14 @@ # Projects Data Source Module -This module extends functionality of [google_projects](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/projects) data source by retrieving all the projects and folders under a specific `parent` recursively. +This module extends functionality of [google_projects](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/projects) data source by retrieving all the projects under a specific `parent` recursively with only one API call against [Cloud Asset Inventory](https://cloud.google.com/asset-inventory) service. A good usage pattern would be when we want all the projects under a specific folder (including nested subfolders) to be included into [VPC Service Controls](../vpc-sc/). Instead of manually maintaining the list of project numbers as an input to the `vpc-sc` module we can use that module to retrieve all the project numbers dynamically. +### IAM Permissions required + +- `roles/cloudasset.viewer` on the `parent` level or above + + ## Examples ### All projects in my org @@ -14,12 +19,8 @@ module "my-org" { parent = "organizations/123456789" } -output "projects" { - value = module.my-org.projects -} - -output "folders" { - value = module.my-org.folders +output "project_numbers" { + value = module.my-org.project_numbers } # tftest skip (uses data sources) @@ -31,18 +32,46 @@ output "folders" { module "my-dev" { source = "./fabric/modules/projects-data-source" parent = "folders/123456789" - filter = "labels.env:DEV lifecycleState:ACTIVE" + query = "labels.env:DEV state:ACTIVE" } output "dev-projects" { value = module.my-dev.projects } -output "dev-folders" { - value = module.my-dev.folders +# tftest skip (uses data sources) +``` + +### Projects under org with folder/project exclusions +```hcl +module "my-filtered" { + source = "./fabric/modules/projects-data-source" + parent = "organizations/123456789" + ignore_projects = [ + "sandbox-*", # wildcard ignore + "project-full-id", # specific project id + "0123456789" # specific project number + ] + + include_projects = [ + "sandbox-114", # include specific project which was excluded by wildcard + "415216609246" # include specific project which was excluded by wildcard (by project number) + ] + + ignore_folders = [ # subfolders are ingoner as well + "343991594985", + "437102807785", + "345245235245" + ] + query = "state:ACTIVE" +} + +output "filtered-projects" { + value = module.my-filtered.projects } # tftest skip (uses data sources) + ``` @@ -50,15 +79,17 @@ output "dev-folders" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [parent](variables.tf#L23) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | ✓ | | -| [filter](variables.tf#L17) | A string filter as defined in the [REST API](https://cloud.google.com/resource-manager/reference/rest/v1/projects/list#query-parameters). | string | | "lifecycleState:ACTIVE" | +| [parent](variables.tf#L55) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string | ✓ | | +| [ignore_folders](variables.tf#L17) | A list of folder IDs or numbers to be excluded from the output, all the subfolders and projects are exluded from the output regardless of the include_projects variable. | list(string) | | [] | +| [ignore_projects](variables.tf#L28) | A list of project IDs, numbers or prefixes to exclude matching projects from the module output. | list(string) | | [] | +| [include_projects](variables.tf#L41) | A list of project IDs/numbers to include to the output if some of them are excluded by `ignore_projects` wilcard entries. | list(string) | | [] | +| [query](variables.tf#L64) | A string query as defined in the [Query Syntax](https://cloud.google.com/asset-inventory/docs/query-syntax). | string | | "state:ACTIVE" | ## Outputs | name | description | sensitive | |---|---|:---:| -| [folders](outputs.tf#L17) | Map of folders attributes keyed by folder id. | | -| [project_numbers](outputs.tf#L22) | List of project numbers. | | -| [projects](outputs.tf#L27) | Map of projects attributes keyed by projects id. | | +| [project_numbers](outputs.tf#L17) | List of project numbers. | | +| [projects](outputs.tf#L22) | List of projects in [StandardResourceMetadata](https://cloud.google.com/asset-inventory/docs/reference/rest/v1p1beta1/resources/searchAll#StandardResourceMetadata) format. | | diff --git a/modules/projects-data-source/main.tf b/modules/projects-data-source/main.tf index 76df425e5c..6bd5631ccf 100644 --- a/modules/projects-data-source/main.tf +++ b/modules/projects-data-source/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -15,129 +15,27 @@ */ locals { - folders_l1_map = { for item in data.google_folders.folders_l1.folders : item.name => item } - - folders_l2_map = merge([ - for _, v in data.google_folders.folders_l2 : - { for item in v.folders : item.name => item } - ]...) - - folders_l3_map = merge([ - for _, v in data.google_folders.folders_l3 : - { for item in v.folders : item.name => item } - ]...) - - folders_l4_map = merge([ - for _, v in data.google_folders.folders_l4 : - { for item in v.folders : item.name => item } - ]...) - - folders_l5_map = merge([ - for _, v in data.google_folders.folders_l5 : - { for item in v.folders : item.name => item } - ]...) - - folders_l6_map = merge([ - for _, v in data.google_folders.folders_l6 : - { for item in v.folders : item.name => item } - ]...) - - folders_l7_map = merge([ - for _, v in data.google_folders.folders_l7 : - { for item in v.folders : item.name => item } - ]...) - - folders_l8_map = merge([ - for _, v in data.google_folders.folders_l8 : - { for item in v.folders : item.name => item } - ]...) - - folders_l9_map = merge([ - for _, v in data.google_folders.folders_l9 : - { for item in v.folders : item.name => item } - ]...) - - folders_l10_map = merge([ - for _, v in data.google_folders.folders_l10 : - { for item in v.folders : item.name => item } - ]...) - - all_folders = merge( - local.folders_l1_map, - local.folders_l2_map, - local.folders_l3_map, - local.folders_l4_map, - local.folders_l5_map, - local.folders_l6_map, - local.folders_l7_map, - local.folders_l8_map, - local.folders_l9_map, - local.folders_l10_map + _ignore_folder_numbers = [for folder_id in var.ignore_folders : trimprefix(folder_id, "folders/")] + _ignore_folders_query = join(" AND NOT folders:", concat([""], local._ignore_folder_numbers)) + query = var.query != "" ? ( + format("%s%s", var.query, local._ignore_folders_query) + ) : ( + format("%s%s", var.query, trimprefix(local._ignore_folders_query, " AND ")) ) - parent_ids = toset(concat( - [split("/", var.parent)[1]], - [for k, _ in local.all_folders : split("/", k)[1]] - )) - - projects = merge([ - for _, v in data.google_projects.projects : - { for item in v.projects : item.project_id => item } - ]...) -} - -# 10 datasources are used to cover 10 possible nested layers in GCP organization hirerarcy. -data "google_folders" "folders_l1" { - parent_id = var.parent -} - -data "google_folders" "folders_l2" { - for_each = local.folders_l1_map - parent_id = each.value.name -} - -data "google_folders" "folders_l3" { - for_each = local.folders_l2_map - parent_id = each.value.name -} - -data "google_folders" "folders_l4" { - for_each = local.folders_l3_map - parent_id = each.value.name -} - -data "google_folders" "folders_l5" { - for_each = local.folders_l4_map - parent_id = each.value.name -} - -data "google_folders" "folders_l6" { - for_each = local.folders_l5_map - parent_id = each.value.name -} - -data "google_folders" "folders_l7" { - for_each = local.folders_l6_map - parent_id = each.value.name -} - -data "google_folders" "folders_l8" { - for_each = local.folders_l7_map - parent_id = each.value.name -} - -data "google_folders" "folders_l9" { - for_each = local.folders_l8_map - parent_id = each.value.name -} - -data "google_folders" "folders_l10" { - for_each = local.folders_l9_map - parent_id = each.value.name -} - -# Getting all projects parented by any of the folders in the tree including root prg/folder provided by `parent` variable. -data "google_projects" "projects" { - for_each = local.parent_ids - filter = "parent.id:${each.value} ${var.filter}" + ignore_patterns = [for item in var.ignore_projects : "^${replace(item, "*", ".*")}$"] + ignore_regexp = length(local.ignore_patterns) > 0 ? join("|", local.ignore_patterns) : "^NO_PROJECTS_TO_IGNORE$" + projects_after_ignore = [for item in data.google_cloud_asset_resources_search_all.projects.results : item if( + length(concat(try(regexall(local.ignore_regexp, trimprefix(item.project, "projects/")), []), try(regexall(local.ignore_regexp, trimprefix(item.name, "//cloudresourcemanager.googleapis.com/projects/")), []))) == 0 + ) || contains(var.include_projects, trimprefix(item.name, "//cloudresourcemanager.googleapis.com/projects/")) || contains(var.include_projects, trimprefix(item.project, "projects/")) + ] +} + +data "google_cloud_asset_resources_search_all" "projects" { + provider = google-beta + scope = var.parent + asset_types = [ + "cloudresourcemanager.googleapis.com/Project" + ] + query = local.query } diff --git a/modules/projects-data-source/outputs.tf b/modules/projects-data-source/outputs.tf index b7e38ae2cf..b1710fa20b 100644 --- a/modules/projects-data-source/outputs.tf +++ b/modules/projects-data-source/outputs.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -14,17 +14,12 @@ * limitations under the License. */ -output "folders" { - description = "Map of folders attributes keyed by folder id." - value = local.all_folders -} - output "project_numbers" { description = "List of project numbers." - value = [for _, v in local.projects : v.number] + value = [for item in local.projects_after_ignore : trimprefix(item.project, "projects/")] } output "projects" { - description = "Map of projects attributes keyed by projects id." - value = local.projects + description = "List of projects in [StandardResourceMetadata](https://cloud.google.com/asset-inventory/docs/reference/rest/v1p1beta1/resources/searchAll#StandardResourceMetadata) format." + value = local.projects_after_ignore } diff --git a/modules/projects-data-source/variables.tf b/modules/projects-data-source/variables.tf index a7f393d335..9fef35ab6c 100644 --- a/modules/projects-data-source/variables.tf +++ b/modules/projects-data-source/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -14,10 +14,42 @@ * limitations under the License. */ -variable "filter" { - description = "A string filter as defined in the [REST API](https://cloud.google.com/resource-manager/reference/rest/v1/projects/list#query-parameters)." - type = string - default = "lifecycleState:ACTIVE" +variable "ignore_folders" { + description = "A list of folder IDs or numbers to be excluded from the output, all the subfolders and projects are exluded from the output regardless of the include_projects variable." + type = list(string) + default = [] + # example exlusing a folder + # ignore_folders = [ + # "folders/0123456789", + # "2345678901" + # ] +} + +variable "ignore_projects" { + description = "A list of project IDs, numbers or prefixes to exclude matching projects from the module output." + type = list(string) + default = [] + # example + #ignore_projects = [ + # "dev-proj-1", + # "uat-proj-2", + # "0123456789", + # "prd-proj-*" + #] +} + +variable "include_projects" { + description = "A list of project IDs/numbers to include to the output if some of them are excluded by `ignore_projects` wilcard entries." + type = list(string) + default = [] + # example excluding all the projects starting with "prf-" except "prd-123457" + #ignore_projects = [ + # "prd-*" + #] + #include_projects = [ + # "prd-123457", + # "0123456789" + #] } variable "parent" { @@ -28,3 +60,9 @@ variable "parent" { error_message = "Parent must be of the form folders/folder_id or organizations/organization_id." } } + +variable "query" { + description = "A string query as defined in the [Query Syntax](https://cloud.google.com/asset-inventory/docs/query-syntax)." + type = string + default = "state:ACTIVE" +} diff --git a/modules/projects-data-source/versions.tf b/modules/projects-data-source/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/projects-data-source/versions.tf +++ b/modules/projects-data-source/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/pubsub/versions.tf b/modules/pubsub/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/pubsub/versions.tf +++ b/modules/pubsub/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/secret-manager/versions.tf b/modules/secret-manager/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/secret-manager/versions.tf +++ b/modules/secret-manager/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/service-directory/versions.tf b/modules/service-directory/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/service-directory/versions.tf +++ b/modules/service-directory/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/source-repository/versions.tf b/modules/source-repository/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/source-repository/versions.tf +++ b/modules/source-repository/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/modules/vpc-sc/README.md b/modules/vpc-sc/README.md index 8e412bcfa6..7ad0cba53f 100644 --- a/modules/vpc-sc/README.md +++ b/modules/vpc-sc/README.md @@ -147,8 +147,8 @@ module "test" { from = { identities = [ "serviceAccount:test-tf@myproject.iam.gserviceaccount.com", - ], - source_access_levels = ["*"] + ] + access_levels = ["*"] } to = { operations = [{ service_name = "*" }] diff --git a/modules/vpc-sc/service-perimeters-bridge.tf b/modules/vpc-sc/service-perimeters-bridge.tf index e3233082c0..c3ca5cae6f 100644 --- a/modules/vpc-sc/service-perimeters-bridge.tf +++ b/modules/vpc-sc/service-perimeters-bridge.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * 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. @@ -27,15 +27,22 @@ resource "google_access_context_manager_service_perimeter" "bridge" { title = each.key perimeter_type = "PERIMETER_TYPE_BRIDGE" use_explicit_dry_run_spec = each.value.use_explicit_dry_run_spec - spec { - resources = each.value.spec_resources == null ? [] : each.value.spec_resources + + dynamic "spec" { + for_each = each.value.spec_resources == null ? [] : [""] + content { + resources = each.value.spec_resources + } } + status { resources = each.value.status_resources == null ? [] : each.value.status_resources } + # lifecycle { # ignore_changes = [spec[0].resources, status[0].resources] # } + depends_on = [ google_access_context_manager_access_policy.default, google_access_context_manager_access_level.basic, diff --git a/modules/vpc-sc/versions.tf b/modules/vpc-sc/versions.tf index 08492c6f95..cef924ea40 100644 --- a/modules/vpc-sc/versions.tf +++ b/modules/vpc-sc/versions.tf @@ -17,11 +17,11 @@ terraform { required_providers { google = { source = "hashicorp/google" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } google-beta = { source = "hashicorp/google-beta" - version = ">= 4.50.0" # tftest + version = ">= 4.55.0" # tftest } } } diff --git a/tests/blueprints/apigee/bigquery-analytics/__init__.py b/tests/blueprints/apigee/bigquery-analytics/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/apigee/bigquery-analytics/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/apigee/bigquery-analytics/basic.tfvars b/tests/blueprints/apigee/bigquery-analytics/basic.tfvars deleted file mode 100644 index 2f9315a439..0000000000 --- a/tests/blueprints/apigee/bigquery-analytics/basic.tfvars +++ /dev/null @@ -1,24 +0,0 @@ -project_create = { - billing_account_id = "12345-12345-12345" - parent = "folders/123456789" -} -project_id = "my-project" -envgroups = { - test = ["test.cool-demos.space"] -} -environments = { - apis-test = { - envgroups = ["test"] - } -} -instances = { - instance-ew1 = { - region = "europe-west1" - environments = ["apis-test"] - runtime_ip_cidr_range = "10.0.4.0/22" - troubleshooting_ip_cidr_range = "10.1.0.0/28" - } -} -psc_config = { - europe-west1 = "10.0.0.0/28" -} diff --git a/tests/blueprints/apigee/bigquery-analytics/basic.yaml b/tests/blueprints/apigee/bigquery-analytics/basic.yaml deleted file mode 100644 index 691af456b1..0000000000 --- a/tests/blueprints/apigee/bigquery-analytics/basic.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2022 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. - -counts: - modules: 9 - resources: 62 diff --git a/tests/blueprints/apigee/bigquery-analytics/tftest.yaml b/tests/blueprints/apigee/bigquery-analytics/tftest.yaml deleted file mode 100644 index a3441f5596..0000000000 --- a/tests/blueprints/apigee/bigquery-analytics/tftest.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2022 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. - -module: blueprints/apigee/bigquery-analytics - -tests: - basic: diff --git a/tests/blueprints/apigee/hybrid-gke/__init__.py b/tests/blueprints/apigee/hybrid-gke/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/apigee/hybrid-gke/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/apigee/hybrid-gke/basic.tfvars b/tests/blueprints/apigee/hybrid-gke/basic.tfvars deleted file mode 100644 index 5b2cb4ccf6..0000000000 --- a/tests/blueprints/apigee/hybrid-gke/basic.tfvars +++ /dev/null @@ -1,6 +0,0 @@ -project_create = { - billing_account_id = "12345-12345-12345" - parent = "folders/123456789" -} -project_id = "my-project" -hostname = "test.myorg.org" \ No newline at end of file diff --git a/tests/blueprints/apigee/hybrid-gke/basic.yaml b/tests/blueprints/apigee/hybrid-gke/basic.yaml deleted file mode 100644 index 0bab564189..0000000000 --- a/tests/blueprints/apigee/hybrid-gke/basic.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2022 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. - -counts: - modules: 17 - resources: 59 diff --git a/tests/blueprints/apigee/hybrid-gke/tftest.yaml b/tests/blueprints/apigee/hybrid-gke/tftest.yaml deleted file mode 100644 index ebe16e577e..0000000000 --- a/tests/blueprints/apigee/hybrid-gke/tftest.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2022 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. - -module: blueprints/apigee/hybrid-gke - -tests: - basic: diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars deleted file mode 100644 index ae07c514fd..0000000000 --- a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars +++ /dev/null @@ -1,5 +0,0 @@ -billing_account_id = "12345-12345-12345" -parent = "folders/123456789" -apigee_project_id = "my-apigee-project" -onprem_project_id = "my-onprem-project" -hostname = "test.myorg.org" diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml deleted file mode 100644 index de461ff2ea..0000000000 --- a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright 2022 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. - -counts: - modules: 13 - resources: 73 diff --git a/tests/blueprints/cloud_operations/__init__.py b/tests/blueprints/cloud_operations/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/adfs/__init__.py b/tests/blueprints/cloud_operations/adfs/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/adfs/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/adfs/fixture/main.tf b/tests/blueprints/cloud_operations/adfs/fixture/main.tf deleted file mode 100644 index ac5a4133db..0000000000 --- a/tests/blueprints/cloud_operations/adfs/fixture/main.tf +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/adfs" - prefix = var.prefix - project_create = var.project_create - project_id = var.project_id - ad_dns_domain_name = var.ad_dns_domain_name - adfs_dns_domain_name = var.adfs_dns_domain_name -} diff --git a/tests/blueprints/cloud_operations/adfs/fixture/variables.tf b/tests/blueprints/cloud_operations/adfs/fixture/variables.tf deleted file mode 100644 index 2fb54b546d..0000000000 --- a/tests/blueprints/cloud_operations/adfs/fixture/variables.tf +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -# Copyright 2022 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 -# -# https://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. - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "12345-12345-12345" - parent = "folders/123456789" - } -} - -variable "project_id" { - type = string - default = "my-project" -} - -variable "prefix" { - type = string - default = "test" -} - -variable "network_config" { - type = object({ - network = string - subnet = string - }) - default = null -} - -variable "ad_dns_domain_name" { - type = string - default = "example.com" -} - -variable "adfs_dns_domain_name" { - type = string - default = "adfs.example.com" -} - -variable "disk_size" { - type = number - default = 50 -} - -variable "disk_type" { - type = string - default = "pd-ssd" -} - -variable "image" { - type = string - default = "projects/windows-cloud/global/images/family/windows-2022" -} - -variable "instance_type" { - type = string - default = "n1-standard-2" -} - -variable "region" { - type = string - default = "europe-west1" -} - -variable "zone" { - type = string - default = "europe-west1-c" -} - -variable "ad_ip_cidr_block" { - type = string - default = "10.0.0.0/24" -} - -variable "subnet_ip_cidr_block" { - type = string - default = "10.0.1.0/28" -} diff --git a/tests/blueprints/cloud_operations/adfs/test_plan.py b/tests/blueprints/cloud_operations/adfs/test_plan.py deleted file mode 100644 index c9682f2d28..0000000000 --- a/tests/blueprints/cloud_operations/adfs/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 4 - assert len(resources) == 15 diff --git a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/__init__.py b/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/cf/README b/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/cf/README deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/main.tf b/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/main.tf deleted file mode 100644 index 83f86c9635..0000000000 --- a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/main.tf +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/asset-inventory-feed-remediation" - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/variables.tf b/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/variables.tf deleted file mode 100644 index 3d884c2522..0000000000 --- a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/fixture/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "project-1" -} diff --git a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/test_plan.py b/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/test_plan.py deleted file mode 100644 index 497af6be59..0000000000 --- a/tests/blueprints/cloud_operations/asset_inventory_feed_remediation/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 6 - assert len(resources) == 19 diff --git a/tests/blueprints/cloud_operations/dns_fine_grained_iam/__init__.py b/tests/blueprints/cloud_operations/dns_fine_grained_iam/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/dns_fine_grained_iam/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/dns_fine_grained_iam/fixture/main.tf b/tests/blueprints/cloud_operations/dns_fine_grained_iam/fixture/main.tf deleted file mode 100644 index ed8a914e7f..0000000000 --- a/tests/blueprints/cloud_operations/dns_fine_grained_iam/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/dns-fine-grained-iam" - name = var.name - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/cloud_operations/dns_fine_grained_iam/fixture/variables.tf b/tests/blueprints/cloud_operations/dns_fine_grained_iam/fixture/variables.tf deleted file mode 100644 index 4f92d75d74..0000000000 --- a/tests/blueprints/cloud_operations/dns_fine_grained_iam/fixture/variables.tf +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "name" { - type = string - default = "dns-sd-test" -} - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "test" -} - -variable "region" { - type = string - default = "europe-west1" -} - -variable "zone_domain" { - type = string - default = "svc.example.org." -} diff --git a/tests/blueprints/cloud_operations/dns_fine_grained_iam/test_plan.py b/tests/blueprints/cloud_operations/dns_fine_grained_iam/test_plan.py deleted file mode 100644 index 111d753b4c..0000000000 --- a/tests/blueprints/cloud_operations/dns_fine_grained_iam/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 8 - assert len(resources) == 25 diff --git a/tests/blueprints/cloud_operations/dns_shared_vpc/__init__.py b/tests/blueprints/cloud_operations/dns_shared_vpc/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/dns_shared_vpc/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/dns_shared_vpc/fixture/main.tf b/tests/blueprints/cloud_operations/dns_shared_vpc/fixture/main.tf deleted file mode 100644 index 78ae428114..0000000000 --- a/tests/blueprints/cloud_operations/dns_shared_vpc/fixture/main.tf +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/dns-shared-vpc" - billing_account_id = "111111-222222-333333" - folder_id = "folders/1234567890" - prefix = var.prefix - shared_vpc_link = "https://www.googleapis.com/compute/v1/projects/test-dns/global/networks/default" - teams = var.teams -} diff --git a/tests/blueprints/cloud_operations/dns_shared_vpc/fixture/variables.tf b/tests/blueprints/cloud_operations/dns_shared_vpc/fixture/variables.tf deleted file mode 100644 index dd34e4d5c3..0000000000 --- a/tests/blueprints/cloud_operations/dns_shared_vpc/fixture/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "prefix" { - type = string - default = "test" -} - -variable "teams" { - type = list(string) - default = ["team1", "team2"] -} diff --git a/tests/blueprints/cloud_operations/dns_shared_vpc/test_plan.py b/tests/blueprints/cloud_operations/dns_shared_vpc/test_plan.py deleted file mode 100644 index 37e9d5b9c7..0000000000 --- a/tests/blueprints/cloud_operations/dns_shared_vpc/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 8 - assert len(resources) == 12 diff --git a/tests/blueprints/cloud_operations/iam_delegated_role_grants/__init__.py b/tests/blueprints/cloud_operations/iam_delegated_role_grants/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/iam_delegated_role_grants/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/iam_delegated_role_grants/fixture/main.tf b/tests/blueprints/cloud_operations/iam_delegated_role_grants/fixture/main.tf deleted file mode 100644 index 655439cfa9..0000000000 --- a/tests/blueprints/cloud_operations/iam_delegated_role_grants/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/iam-delegated-role-grants" - project_create = true - project_id = var.project_id - project_administrators = ["user:user@example.com"] -} diff --git a/tests/blueprints/cloud_operations/iam_delegated_role_grants/test_plan.py b/tests/blueprints/cloud_operations/iam_delegated_role_grants/test_plan.py deleted file mode 100644 index 291ffe133e..0000000000 --- a/tests/blueprints/cloud_operations/iam_delegated_role_grants/test_plan.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(include_bare_resources=True) - assert len(modules) == 1 - assert len(resources) == 4 - -# TODO(jccb): test audit function (requires extending requirement for -# test suite) -# def test_audit(): -# AUDIT_PATH = os.path.join(os.path.dirname(__file__), "../../../cloud-operations/delegated-role-grants/") -# sys.path.append(AUDIT_PATH) -# import audit diff --git a/tests/blueprints/cloud_operations/onprem_sa_key_management/__init__.py b/tests/blueprints/cloud_operations/onprem_sa_key_management/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/onprem_sa_key_management/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/onprem_sa_key_management/fixture/main.tf b/tests/blueprints/cloud_operations/onprem_sa_key_management/fixture/main.tf deleted file mode 100644 index 29e473f024..0000000000 --- a/tests/blueprints/cloud_operations/onprem_sa_key_management/fixture/main.tf +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/onprem-sa-key-management" - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/cloud_operations/onprem_sa_key_management/fixture/variables.tf b/tests/blueprints/cloud_operations/onprem_sa_key_management/fixture/variables.tf deleted file mode 100644 index ab2117be32..0000000000 --- a/tests/blueprints/cloud_operations/onprem_sa_key_management/fixture/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "test" -} diff --git a/tests/blueprints/cloud_operations/onprem_sa_key_management/test_plan.py b/tests/blueprints/cloud_operations/onprem_sa_key_management/test_plan.py deleted file mode 100644 index 0382fd0ed0..0000000000 --- a/tests/blueprints/cloud_operations/onprem_sa_key_management/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 3 - assert len(resources) == 7 diff --git a/tests/blueprints/cloud_operations/packer_image_builder/__init__.py b/tests/blueprints/cloud_operations/packer_image_builder/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/packer_image_builder/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/packer_image_builder/fixture/main.tf b/tests/blueprints/cloud_operations/packer_image_builder/fixture/main.tf deleted file mode 100644 index 6dec6b25bf..0000000000 --- a/tests/blueprints/cloud_operations/packer_image_builder/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/packer-image-builder" - project_id = "test-project" - packer_account_users = ["user:john@testdomain.com"] - create_packer_vars = var.create_packer_vars -} diff --git a/tests/blueprints/cloud_operations/packer_image_builder/fixture/packer/build.pkrvars.tpl b/tests/blueprints/cloud_operations/packer_image_builder/fixture/packer/build.pkrvars.tpl deleted file mode 100644 index 9864dc2bd7..0000000000 --- a/tests/blueprints/cloud_operations/packer_image_builder/fixture/packer/build.pkrvars.tpl +++ /dev/null @@ -1,8 +0,0 @@ -# Packer variables file template. -# Used by Terraform to generate Packer variable file. -project_id = "${PROJECT_ID}" -compute_zone = "${COMPUTE_ZONE}" -builder_sa = "${BUILDER_SA}" -compute_sa = "${COMPUTE_SA}" -compute_subnetwork = "${COMPUTE_SUBNETWORK}" -use_iap = ${USE_IAP} \ No newline at end of file diff --git a/tests/blueprints/cloud_operations/packer_image_builder/test_plan.py b/tests/blueprints/cloud_operations/packer_image_builder/test_plan.py deleted file mode 100644 index c3b9b8f40b..0000000000 --- a/tests/blueprints/cloud_operations/packer_image_builder/test_plan.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2022 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. - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(include_bare_resources="true") - - assert len(modules) == 6 - assert len(resources) == 16 - - modules, resources = e2e_plan_runner(include_bare_resources="true", - create_packer_vars="true") - assert len(modules) == 6 - assert len(resources) == 17 diff --git a/tests/blueprints/cloud_operations/quota_monitoring/__init__.py b/tests/blueprints/cloud_operations/quota_monitoring/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/quota_monitoring/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/quota_monitoring/fixture/cf/README b/tests/blueprints/cloud_operations/quota_monitoring/fixture/cf/README deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/blueprints/cloud_operations/quota_monitoring/fixture/main.tf b/tests/blueprints/cloud_operations/quota_monitoring/fixture/main.tf deleted file mode 100644 index ef26ea0b73..0000000000 --- a/tests/blueprints/cloud_operations/quota_monitoring/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/quota-monitoring" - name = var.name - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/cloud_operations/quota_monitoring/fixture/variables.tf b/tests/blueprints/cloud_operations/quota_monitoring/fixture/variables.tf deleted file mode 100644 index 4f92d75d74..0000000000 --- a/tests/blueprints/cloud_operations/quota_monitoring/fixture/variables.tf +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "name" { - type = string - default = "dns-sd-test" -} - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "test" -} - -variable "region" { - type = string - default = "europe-west1" -} - -variable "zone_domain" { - type = string - default = "svc.example.org." -} diff --git a/tests/blueprints/cloud_operations/quota_monitoring/test_plan.py b/tests/blueprints/cloud_operations/quota_monitoring/test_plan.py deleted file mode 100644 index 1de0c31269..0000000000 --- a/tests/blueprints/cloud_operations/quota_monitoring/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 3 - assert len(resources) == 10 diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/__init__.py b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/bundle_cffile.zip b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/bundle_cffile.zip deleted file mode 100644 index 454bc1f7c7..0000000000 Binary files a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/bundle_cffile.zip and /dev/null differ diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/cf/README b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/cf/README deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/cffile/README b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/cffile/README deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/main.tf b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/main.tf deleted file mode 100644 index 05d6325356..0000000000 --- a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/main.tf +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/scheduled-asset-inventory-export-bq" - billing_account = var.billing_account - cai_config = var.cai_config - cai_gcs_export = var.cai_gcs_export - file_config = var.file_config - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/variables.tf b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/variables.tf deleted file mode 100644 index fb30df6073..0000000000 --- a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/fixture/variables.tf +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "billing_account" { - type = string - default = "1234-ABCD-1234" -} - -variable "cai_config" { - type = object({ - bq_dataset = string - bq_table = string - bq_table_overwrite = bool - target_node = string - }) - default = { - bq_dataset = "my-dataset" - bq_table = "my_table" - bq_table_overwrite = "true" - target_node = "organization/1234567890" - } -} - -variable "cai_gcs_export" { - type = bool - default = true -} - -variable "file_config" { - type = object({ - bucket = string - filename = string - format = string - bq_dataset = string - bq_table = string - }) - default = { - bucket = "my-bucket" - filename = "my-folder/myfile.json" - format = "NEWLINE_DELIMITED_JSON" - bq_dataset = "my-dataset" - bq_table = "my_table" - } -} - - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "project-1" -} diff --git a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/test_plan.py b/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/test_plan.py deleted file mode 100644 index 3bcc634406..0000000000 --- a/tests/blueprints/cloud_operations/scheduled_asset_inventory_export_bq/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 7 - assert len(resources) == 30 diff --git a/tests/blueprints/cloud_operations/terraform_enterprise_wif/__init__.py b/tests/blueprints/cloud_operations/terraform_enterprise_wif/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/terraform_enterprise_wif/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/__init__.py b/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/fixture/main.tf b/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/fixture/main.tf deleted file mode 100644 index 3552740c2a..0000000000 --- a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/fixture/main.tf +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../../blueprints/cloud-operations/terraform-enterprise-wif/gcp-workload-identity-provider" - billing_account = var.billing_account - project_create = var.project_create - project_id = var.project_id - parent = var.parent - tfe_organization_id = var.tfe_organization_id - tfe_workspace_id = var.tfe_workspace_id - workload_identity_pool_id = var.workload_identity_pool_id - workload_identity_pool_provider_id = var.workload_identity_pool_provider_id - issuer_uri = var.issuer_uri -} diff --git a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/fixture/variables.tf b/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/fixture/variables.tf deleted file mode 100644 index d99981c0cf..0000000000 --- a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/fixture/variables.tf +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "billing_account" { - type = string - default = "1234-ABCD-1234" -} - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "project-1" -} - -variable "parent" { - description = "Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format." - type = string - default = null - validation { - condition = var.parent == null || can(regex("(organizations|folders)/[0-9]+", var.parent)) - error_message = "Parent must be of the form folders/folder_id or organizations/organization_id." - } -} - -variable "tfe_organization_id" { - description = "TFE organization id." - type = string - default = "org-123" -} - -variable "tfe_workspace_id" { - description = "TFE workspace id." - type = string - default = "ws-123" -} - -variable "workload_identity_pool_id" { - description = "Workload identity pool id." - type = string - default = "tfe-pool" -} - -variable "workload_identity_pool_provider_id" { - description = "Workload identity pool provider id." - type = string - default = "tfe-provider" -} - -variable "issuer_uri" { - description = "Terraform Enterprise uri. Replace the uri if a self hosted instance is used." - type = string - default = "https://app.terraform.io/" -} diff --git a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/test_plan.py b/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/test_plan.py deleted file mode 100644 index 228e51dfde..0000000000 --- a/tests/blueprints/cloud_operations/terraform_enterprise_wif/gcp_workload_identity_provider/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 2 - assert len(resources) == 10 diff --git a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/__init__.py b/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/fixture/main.tf b/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/fixture/main.tf deleted file mode 100644 index 22b5da3c9c..0000000000 --- a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/cloud-operations/unmanaged-instances-healthcheck" - billing_account = var.billing_account - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/fixture/variables.tf b/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/fixture/variables.tf deleted file mode 100644 index fb30df6073..0000000000 --- a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/fixture/variables.tf +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "billing_account" { - type = string - default = "1234-ABCD-1234" -} - -variable "cai_config" { - type = object({ - bq_dataset = string - bq_table = string - bq_table_overwrite = bool - target_node = string - }) - default = { - bq_dataset = "my-dataset" - bq_table = "my_table" - bq_table_overwrite = "true" - target_node = "organization/1234567890" - } -} - -variable "cai_gcs_export" { - type = bool - default = true -} - -variable "file_config" { - type = object({ - bucket = string - filename = string - format = string - bq_dataset = string - bq_table = string - }) - default = { - bucket = "my-bucket" - filename = "my-folder/myfile.json" - format = "NEWLINE_DELIMITED_JSON" - bq_dataset = "my-dataset" - bq_table = "my_table" - } -} - - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "project-1" -} diff --git a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/test_plan.py b/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/test_plan.py deleted file mode 100644 index b1f0fba3ca..0000000000 --- a/tests/blueprints/cloud_operations/unmanaged_instances_healthcheck/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 10 - assert len(resources) == 32 diff --git a/tests/blueprints/cloud_operations/vm_migration/host_target_projects/__init__.py b/tests/blueprints/cloud_operations/vm_migration/host_target_projects/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/host_target_projects/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/vm_migration/host_target_projects/fixture/main.tf b/tests/blueprints/cloud_operations/vm_migration/host_target_projects/fixture/main.tf deleted file mode 100644 index 488dd7ccf6..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/host_target_projects/fixture/main.tf +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -module "host-target-projects-test" { - source = "../../../../../../blueprints/cloud-operations/vm-migration/host-target-projects" - project_create = var.project_create - migration_admin_users = ["user:admin@example.com"] - migration_viewer_users = ["user:viewer@example.com"] - migration_target_projects = ["${module.test-target-project.name}"] - depends_on = [ - module.test-target-project - ] -} - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "1234-ABCD-1234" - parent = "folders/1234563" - } -} - -#This is a dummy project created to run this test. The example, here tested, is expected to run on top of existing foundations. -module "test-target-project" { - source = "../../../../../../modules/project" - billing_account = "1234-ABCD-1234" - name = "test-target-project" - project_create = true -} diff --git a/tests/blueprints/cloud_operations/vm_migration/host_target_projects/test_plan.py b/tests/blueprints/cloud_operations/vm_migration/host_target_projects/test_plan.py deleted file mode 100644 index 33f493bae4..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/host_target_projects/test_plan.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2022 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 os - - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 3 - assert len(resources) == 23 diff --git a/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/__init__.py b/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/fixture/main.tf b/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/fixture/main.tf deleted file mode 100644 index f8bea07c08..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/fixture/main.tf +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -module "host-target-sharedvpc-test" { - source = "../../../../../../blueprints/cloud-operations/vm-migration/host-target-sharedvpc" - project_create = var.project_create - migration_admin_users = ["user:admin@example.com"] - migration_viewer_users = ["user:viewer@example.com"] - migration_target_projects = [module.test-target-project.name] - sharedvpc_host_projects = [module.test-sharedvpc-host-project.name] - depends_on = [ - module.test-target-project, - module.test-sharedvpc-host-project, - ] -} - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "1234-ABCD-1234" - parent = "folders/1234563" - } -} - -#These are a dummy projects created to run this test. The example, here tested, is expected to run on top of existing foundations. -module "test-target-project" { - source = "../../../../../../modules/project" - billing_account = "1234-ABCD-1234" - name = "test-target-project" - project_create = true -} -module "test-sharedvpc-host-project" { - source = "../../../../../../modules/project" - billing_account = "1234-ABCD-1234" - name = "test-sharedvpc-host-project" - project_create = true -} diff --git a/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/test_plan.py b/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/test_plan.py deleted file mode 100644 index 839357118a..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/host_target_sharedvpc/test_plan.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2022 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 os - - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 4 - assert len(resources) == 23 diff --git a/tests/blueprints/cloud_operations/vm_migration/single_project/__init__.py b/tests/blueprints/cloud_operations/vm_migration/single_project/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/single_project/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/cloud_operations/vm_migration/single_project/fixture/main.tf b/tests/blueprints/cloud_operations/vm_migration/single_project/fixture/main.tf deleted file mode 100644 index ccb46d5416..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/single_project/fixture/main.tf +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -module "single-project-test" { - source = "../../../../../../blueprints/cloud-operations/vm-migration/single-project" - project_create = var.project_create - migration_admin_users = ["user:admin@example.com"] - migration_viewer_users = ["user:viewer@example.com"] -} - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "1234-ABCD-1234" - parent = "folders/1234563" - } -} diff --git a/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py b/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py deleted file mode 100644 index 6e2c141da5..0000000000 --- a/tests/blueprints/cloud_operations/vm_migration/single_project/test_plan.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2022 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 os - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 4 - assert len(resources) == 20 diff --git a/tests/blueprints/data_solutions/__init__.py b/tests/blueprints/data_solutions/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/cloudsql_multiregion/__init__.py b/tests/blueprints/data_solutions/cloudsql_multiregion/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/cloudsql_multiregion/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/cloudsql_multiregion/fixture/main.tf b/tests/blueprints/data_solutions/cloudsql_multiregion/fixture/main.tf deleted file mode 100644 index 3d71614976..0000000000 --- a/tests/blueprints/data_solutions/cloudsql_multiregion/fixture/main.tf +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/cloudsql-multiregion/" - data_eng_principals = ["dataeng@example.com"] - postgres_user_password = "my-root-password" - project_id = "project" - project_create = { - billing_account_id = "123456-123456-123456" - parent = "folders/12345678" - } - prefix = "prefix" -} diff --git a/tests/blueprints/data_solutions/cloudsql_multiregion/test_plan.py b/tests/blueprints/data_solutions/cloudsql_multiregion/test_plan.py deleted file mode 100644 index 90371cf7c7..0000000000 --- a/tests/blueprints/data_solutions/cloudsql_multiregion/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 9 - assert len(resources) == 48 diff --git a/tests/blueprints/data_solutions/cmek_via_centralized_kms/__init__.py b/tests/blueprints/data_solutions/cmek_via_centralized_kms/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/cmek_via_centralized_kms/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/cmek_via_centralized_kms/fixture/main.tf b/tests/blueprints/data_solutions/cmek_via_centralized_kms/fixture/main.tf deleted file mode 100644 index 3fee8af5f0..0000000000 --- a/tests/blueprints/data_solutions/cmek_via_centralized_kms/fixture/main.tf +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/cmek-via-centralized-kms/" - project_config = { - billing_account_id = "123456-123456-123456" - parent = "folders/12345678" - } - prefix = "prefix" -} diff --git a/tests/blueprints/data_solutions/cmek_via_centralized_kms/test_plan.py b/tests/blueprints/data_solutions/cmek_via_centralized_kms/test_plan.py deleted file mode 100644 index 22d474b431..0000000000 --- a/tests/blueprints/data_solutions/cmek_via_centralized_kms/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 7 - assert len(resources) == 27 diff --git a/tests/blueprints/data_solutions/composer_2/__init__.py b/tests/blueprints/data_solutions/composer_2/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/composer_2/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/composer_2/fixture/main.tf b/tests/blueprints/data_solutions/composer_2/fixture/main.tf deleted file mode 100644 index 4b35e6f80e..0000000000 --- a/tests/blueprints/data_solutions/composer_2/fixture/main.tf +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/composer-2/" - project_id = "project" - - project_create = { - billing_account_id = "123456-123456-123456" - parent = "folders/12345678" - } - prefix = "prefix" -} diff --git a/tests/blueprints/data_solutions/composer_2/test_plan.py b/tests/blueprints/data_solutions/composer_2/test_plan.py deleted file mode 100644 index 04f4a39f71..0000000000 --- a/tests/blueprints/data_solutions/composer_2/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 4 - assert len(resources) == 25 diff --git a/tests/blueprints/data_solutions/data_platform_foundations/__init__.py b/tests/blueprints/data_solutions/data_platform_foundations/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/data_platform_foundations/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/data_platform_foundations/fixture/main.tf b/tests/blueprints/data_solutions/data_platform_foundations/fixture/main.tf deleted file mode 100644 index 52317d6f5f..0000000000 --- a/tests/blueprints/data_solutions/data_platform_foundations/fixture/main.tf +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/data-platform-foundations/" - organization_domain = "example.com" - billing_account_id = "123456-123456-123456" - folder_id = "folders/12345678" - prefix = "prefix" -} diff --git a/tests/blueprints/data_solutions/data_platform_foundations/test_plan.py b/tests/blueprints/data_solutions/data_platform_foundations/test_plan.py deleted file mode 100644 index 785f470537..0000000000 --- a/tests/blueprints/data_solutions/data_platform_foundations/test_plan.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2022 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 os -import pytest - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - - assert len(modules) == 42 - assert len(resources) == 296 diff --git a/tests/blueprints/data_solutions/data_playground/__init__.py b/tests/blueprints/data_solutions/data_playground/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/data_playground/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/data_playground/fixture/main.tf b/tests/blueprints/data_solutions/data_playground/fixture/main.tf deleted file mode 100644 index e9e1d29798..0000000000 --- a/tests/blueprints/data_solutions/data_playground/fixture/main.tf +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/data-playground/" - project_id = "sampleproject" - prefix = "tst" - project_create = { - billing_account_id = "123456-123456-123456", - parent = "folders/467898377" - } -} diff --git a/tests/blueprints/data_solutions/data_playground/test_plan.py b/tests/blueprints/data_solutions/data_playground/test_plan.py deleted file mode 100644 index daaa57fc96..0000000000 --- a/tests/blueprints/data_solutions/data_playground/test_plan.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2022 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 os -import pytest - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 7 - assert len(resources) == 38 diff --git a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/__init__.py b/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/fixture/main.tf b/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/fixture/main.tf deleted file mode 100644 index 4fc83c755b..0000000000 --- a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/gcs-to-bq-with-least-privileges/" - project_create = var.project_create - project_id = var.project_id - prefix = var.prefix -} diff --git a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/fixture/variables.tf b/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/fixture/variables.tf deleted file mode 100644 index 477dcaf792..0000000000 --- a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/fixture/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2022 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. - */ - -variable "prefix" { - description = "Unique prefix used for resource names. Not used for project if 'project_create' is null." - type = string - default = "prefix" -} - -variable "project_create" { - description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format." - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "123456-123456-123456" - parent = "folders/12345678" - } -} - -variable "project_id" { - description = "Project id, references existing project if `project_create` is null." - type = string - default = "datalake" -} diff --git a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/test_plan.py b/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/test_plan.py deleted file mode 100644 index 773e80ca17..0000000000 --- a/tests/blueprints/data_solutions/gcs_to_bq_with_least_privileges/test_plan.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2022 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 os -import pytest - - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 11 - assert len(resources) == 47 diff --git a/tests/blueprints/data_solutions/shielded_folder/simple.yaml b/tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml similarity index 78% rename from tests/blueprints/data_solutions/shielded_folder/simple.yaml rename to tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml index 244dcb976e..23bc8b7a09 100644 --- a/tests/blueprints/data_solutions/shielded_folder/simple.yaml +++ b/tests/blueprints/data_solutions/shielded_folder/examples/simple.yaml @@ -13,18 +13,18 @@ # limitations under the License. values: - module.folder.google_compute_firewall_policy.policy["prefix-fw-policy"]: + module.test.module.folder.google_compute_firewall_policy.policy["prefix-fw-policy"]: short_name: prefix-fw-policy - module.folder.google_folder.folder[0]: + module.test.module.folder.google_folder.folder[0]: display_name: ShieldedMVP parent: organizations/1234567890123 - module.log-export-project[0].google_project.project[0]: + module.test.module.log-export-project[0].google_project.project[0]: billing_account: 123456-123456-123456 project_id: prefix-audit-logs - module.vpc-sc[0].google_access_context_manager_access_policy.default[0]: + module.test.module.vpc-sc[0].google_access_context_manager_access_policy.default[0]: parent: organizations/1122334455 title: shielded-folder - module.vpc-sc[0].google_access_context_manager_service_perimeter.regular["shielded"]: + module.test.module.vpc-sc[0].google_access_context_manager_service_perimeter.regular["shielded"]: description: null perimeter_type: PERIMETER_TYPE_REGULAR title: shielded @@ -47,5 +47,5 @@ counts: google_project_service_identity: 1 google_projects: 1 google_storage_project_service_account: 1 - modules: 5 + modules: 6 resources: 38 diff --git a/tests/blueprints/data_solutions/shielded_folder/simple.tfvars b/tests/blueprints/data_solutions/shielded_folder/simple.tfvars deleted file mode 100644 index 83e8b1399c..0000000000 --- a/tests/blueprints/data_solutions/shielded_folder/simple.tfvars +++ /dev/null @@ -1,20 +0,0 @@ -access_policy_config = { - access_policy_create = { - parent = "organizations/1234567890123" - title = "ShieldedMVP" - } -} -folder_config = { - folder_create = { - display_name = "ShieldedMVP" - parent = "organizations/1234567890123" - } -} -organization = { - domain = "example.com" - id = "1122334455" -} -prefix = "prefix" -project_config = { - billing_account_id = "123456-123456-123456" -} diff --git a/tests/blueprints/data_solutions/sqlserver_alwayson/__init__.py b/tests/blueprints/data_solutions/sqlserver_alwayson/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/sqlserver_alwayson/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/sqlserver_alwayson/fixture/main.tf b/tests/blueprints/data_solutions/sqlserver_alwayson/fixture/main.tf deleted file mode 100644 index 72f7a7d337..0000000000 --- a/tests/blueprints/data_solutions/sqlserver_alwayson/fixture/main.tf +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/data-solutions/sqlserver-alwayson/" - project_create = var.project_create - project_id = var.project_id - prefix = var.prefix - network = "example-network" - subnetwork = "example-subnetwork" - sql_admin_password = "password" - ad_domain_fqdn = "ad.example.com" - ad_domain_netbios = "ad" -} diff --git a/tests/blueprints/data_solutions/sqlserver_alwayson/fixture/variables.tf b/tests/blueprints/data_solutions/sqlserver_alwayson/fixture/variables.tf deleted file mode 100644 index e2c50ac27c..0000000000 --- a/tests/blueprints/data_solutions/sqlserver_alwayson/fixture/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2022 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. - */ - -variable "prefix" { - description = "Unique prefix used for resource names." - type = string - default = "test" -} - -variable "project_create" { - description = "Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format." - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "123456-123456-123456" - parent = "folders/12345678" - } -} - -variable "project_id" { - description = "Project id, references existing project if `project_create` is null." - type = string - default = "sqlserver" -} diff --git a/tests/blueprints/data_solutions/sqlserver_alwayson/test_plan.py b/tests/blueprints/data_solutions/sqlserver_alwayson/test_plan.py deleted file mode 100644 index 863148007d..0000000000 --- a/tests/blueprints/data_solutions/sqlserver_alwayson/test_plan.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright 2022 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 os -import pytest - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - assert len(modules) == 11 - assert len(resources) == 38 diff --git a/tests/blueprints/data_solutions/vertex_mlops/__init__.py b/tests/blueprints/data_solutions/vertex_mlops/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/data_solutions/vertex_mlops/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/data_solutions/vertex_mlops/fixture/main.tf b/tests/blueprints/data_solutions/vertex_mlops/fixture/main.tf deleted file mode 100644 index 0b671f3355..0000000000 --- a/tests/blueprints/data_solutions/vertex_mlops/fixture/main.tf +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "projects" { - source = "../../../../../blueprints/data-solutions/vertex-mlops/" - labels = { - "env" : "dev", - "team" : "ml" - } - bucket_name = "test-dev" - dataset_name = "test" - identity_pool_claims = "attribute.repository/ORGANIZATION/REPO" - notebooks = { - "myworkbench" : { - "owner" : "user@example.com", - "region" : "europe-west4", - "subnet" : "default", - } - } - prefix = "pref" - project_id = "test-dev" - project_create = { - billing_account_id = "000000-123456-123456" - parent = "folders/111111111111" - } -} diff --git a/tests/blueprints/data_solutions/vertex_mlops/test_plan.py b/tests/blueprints/data_solutions/vertex_mlops/test_plan.py deleted file mode 100644 index eac30ad57f..0000000000 --- a/tests/blueprints/data_solutions/vertex_mlops/test_plan.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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 os -import pytest - -FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixture') - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner(FIXTURES_DIR) - # TODO: to re-enable per-module resource count check print _, then test - assert len(modules) > 0 and len(resources) > 0 \ No newline at end of file diff --git a/tests/blueprints/factories/cloud_identity_group_factory/__init__.py b/tests/blueprints/factories/cloud_identity_group_factory/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/factories/cloud_identity_group_factory/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/factories/cloud_identity_group_factory/examples/example.yaml b/tests/blueprints/factories/cloud_identity_group_factory/examples/example.yaml new file mode 100644 index 0000000000..1a8db1b593 --- /dev/null +++ b/tests/blueprints/factories/cloud_identity_group_factory/examples/example.yaml @@ -0,0 +1,42 @@ +# 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. + +values: + module.groups.module.group["group1@example.com"].google_cloud_identity_group.group: + description: Group 1 + display_name: Group 1 + group_key: + - id: group1@example.com + namespace: null + initial_group_config: EMPTY + labels: + cloudidentity.googleapis.com/groups.discussion_forum: '' + parent: customers/C0xxxxxxx + module.groups.module.group["group1@example.com"].google_cloud_identity_group_membership.managers["user2@example.com"]: + preferred_member_key: + - id: user2@example.com + namespace: null + roles: + - name: MANAGER + - name: MEMBER + module.groups.module.group["group1@example.com"].google_cloud_identity_group_membership.members["user1@example.com"]: + preferred_member_key: + - id: user1@example.com + namespace: null + roles: + - name: MEMBER + +counts: + google_cloud_identity_group: 1 + google_cloud_identity_group_membership: 2 diff --git a/tests/blueprints/factories/cloud_identity_group_factory/fixture/data/group1@example.com.yaml b/tests/blueprints/factories/cloud_identity_group_factory/fixture/data/group1@example.com.yaml deleted file mode 100644 index 98bdcb8e1e..0000000000 --- a/tests/blueprints/factories/cloud_identity_group_factory/fixture/data/group1@example.com.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# skip boilerplate check - -display_name: Group 1 -description: Group 1 -members: - - user1@example.com -managers: - - user2@example.com \ No newline at end of file diff --git a/tests/blueprints/factories/cloud_identity_group_factory/test_plan.py b/tests/blueprints/factories/cloud_identity_group_factory/test_plan.py deleted file mode 100644 index 7de10b1a5f..0000000000 --- a/tests/blueprints/factories/cloud_identity_group_factory/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 1 - assert len(resources) == 3 diff --git a/tests/blueprints/factories/net_vpc_firewall_yaml/__init__.py b/tests/blueprints/factories/net_vpc_firewall_yaml/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/factories/net_vpc_firewall_yaml/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/factories/net_vpc_firewall_yaml/examples/example.yaml b/tests/blueprints/factories/net_vpc_firewall_yaml/examples/example.yaml new file mode 100644 index 0000000000..c2375ae574 --- /dev/null +++ b/tests/blueprints/factories/net_vpc_firewall_yaml/examples/example.yaml @@ -0,0 +1,188 @@ +# 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. + +values: + module.dev-firewall.google_compute_firewall.rules["deny-all"]: + allow: [] + deny: + - ports: [] + protocol: all + destination_ranges: + - 0.0.0.0/0 + direction: EGRESS + disabled: null + log_config: [] + name: fwr-my-dev-network-all-e-deny-all + network: my-dev-network + priority: 65535 + project: my-dev-project + source_ranges: null + source_service_accounts: null + source_tags: null + target_service_accounts: null + target_tags: null + timeouts: null + module.dev-firewall.google_compute_firewall.rules["lb-health-checks"]: + allow: + - ports: [] + protocol: tcp + deny: [] + direction: INGRESS + disabled: null + log_config: [] + name: fwr-my-dev-network-all-i-lb-health-checks + network: my-dev-network + priority: 1001 + project: my-dev-project + source_ranges: + - 130.211.0.0/22 + - 35.191.0.0/16 + source_service_accounts: null + source_tags: null + target_service_accounts: null + target_tags: null + timeouts: null + module.dev-firewall.google_compute_firewall.rules["web-app-dev-egress"]: + allow: + - ports: + - '443' + protocol: tcp + deny: [] + destination_ranges: + - 192.168.0.0/24 + direction: EGRESS + disabled: null + log_config: [] + name: fwr-my-dev-network-sac-e-web-app-dev-egress + network: my-dev-network + priority: 1000 + project: my-dev-project + source_ranges: null + source_service_accounts: null + source_tags: null + target_service_accounts: + - myapp@myproject-dev.iam.gserviceaccount.com + target_tags: null + timeouts: null + module.dev-firewall.google_compute_firewall.rules["web-app-dev-ingress"]: + allow: + - ports: + - '1234' + protocol: tcp + deny: [] + direction: INGRESS + disabled: null + log_config: [] + name: fwr-my-dev-network-sac-i-web-app-dev-ingress + network: my-dev-network + priority: 1000 + project: my-dev-project + source_ranges: null + source_service_accounts: + - frontend-sa@myproject-dev.iam.gserviceaccount.com + source_tags: null + target_service_accounts: + - web-app-a@myproject-dev.iam.gserviceaccount.com + target_tags: null + timeouts: null + module.prod-firewall.google_compute_firewall.rules["deny-all"]: + allow: [] + deny: + - ports: [] + protocol: all + destination_ranges: + - 0.0.0.0/0 + direction: EGRESS + disabled: null + log_config: + - metadata: INCLUDE_ALL_METADATA + name: fwr-my-prod-network-all-e-deny-all + network: my-prod-network + priority: 65535 + project: my-prod-project + source_ranges: null + source_service_accounts: null + source_tags: null + target_service_accounts: null + target_tags: null + timeouts: null + module.prod-firewall.google_compute_firewall.rules["lb-health-checks"]: + allow: + - ports: [] + protocol: tcp + deny: [] + direction: INGRESS + disabled: null + log_config: + - metadata: INCLUDE_ALL_METADATA + name: fwr-my-prod-network-all-i-lb-health-checks + network: my-prod-network + priority: 1001 + project: my-prod-project + source_ranges: + - 130.211.0.0/22 + - 35.191.0.0/16 + source_service_accounts: null + source_tags: null + target_service_accounts: null + target_tags: null + timeouts: null + module.prod-firewall.google_compute_firewall.rules["web-app-prod-egress"]: + allow: + - ports: + - '443' + protocol: tcp + deny: [] + destination_ranges: + - 192.168.10.0/24 + direction: EGRESS + disabled: null + log_config: + - metadata: INCLUDE_ALL_METADATA + name: fwr-my-prod-network-sac-e-web-app-prod-egress + network: my-prod-network + priority: 1000 + project: my-prod-project + source_ranges: null + source_service_accounts: null + source_tags: null + target_service_accounts: + - myapp@myproject-prod.iam.gserviceaccount.com + target_tags: null + timeouts: null + module.prod-firewall.google_compute_firewall.rules["web-app-prod-ingress"]: + allow: + - ports: + - '1234' + protocol: tcp + deny: [] + direction: INGRESS + disabled: null + log_config: + - metadata: INCLUDE_ALL_METADATA + name: fwr-my-prod-network-sac-i-web-app-prod-ingress + network: my-prod-network + priority: 1000 + project: my-prod-project + source_ranges: null + source_service_accounts: + - frontend-sa@myproject-prod.iam.gserviceaccount.com + source_tags: null + target_service_accounts: + - web-app-a@myproject-prod.iam.gserviceaccount.com + target_tags: null + timeouts: null + +counts: + google_compute_firewall: 8 diff --git a/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/main.tf b/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/main.tf deleted file mode 100644 index 22956f4018..0000000000 --- a/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/main.tf +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "firewall" { - source = "../../../../../blueprints/factories/net-vpc-firewall-yaml" - project_id = "my-project" - network = "my-network" - config_directories = [ - "./rules" - ] - log_config = var.log_config -} diff --git a/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/rules/common.yaml b/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/rules/common.yaml deleted file mode 100644 index cbe8466f01..0000000000 --- a/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/rules/common.yaml +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2022 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. - -# allow ingress from GCLB to all instances in the network -lb-health-checks: - allow: - - ports: [] - protocol: tcp - direction: INGRESS - priority: 1001 - source_ranges: - - 35.191.0.0/16 - - 130.211.0.0/22 - -# deny all egress -deny-all: - deny: - - ports: [] - protocol: all - direction: EGRESS - priority: 65535 - destination_ranges: - - 0.0.0.0/0 diff --git a/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/variables.tf b/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/variables.tf deleted file mode 100644 index 018289febb..0000000000 --- a/tests/blueprints/factories/net_vpc_firewall_yaml/fixture/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2022 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. - */ - -variable "log_config" { - description = "Log configuration. Possible values for `metadata` are `EXCLUDE_ALL_METADATA` and `INCLUDE_ALL_METADATA`. Set to `null` for disabling firewall logging." - type = object({ - metadata = string - }) - default = null -} diff --git a/tests/blueprints/factories/net_vpc_firewall_yaml/test_plan.py b/tests/blueprints/factories/net_vpc_firewall_yaml/test_plan.py deleted file mode 100644 index 80205e57fc..0000000000 --- a/tests/blueprints/factories/net_vpc_firewall_yaml/test_plan.py +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2022 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. - -def test_firewall_simple(plan_runner): - "Test firewall rules from rules/common.yaml with no extra options." - _, resources = plan_runner() - assert len(resources) == 4 - assert set(r['type'] for r in resources) == set([ - 'google_compute_firewall', 'time_static' - ]) - firewall_values = [r['values'] for r in resources if r['type'] - == 'google_compute_firewall'] - assert set([f['project'] for f in firewall_values]) == set(['my-project']) - assert set([f['network'] for f in firewall_values]) == set(['my-network']) - - -def test_firewall_log_config(plan_runner): - "Test firewall rules log configuration." - log_config = """ { - metadata = "INCLUDE_ALL_METADATA" - } - """ - log_config_value = [{"metadata": "INCLUDE_ALL_METADATA"}] - _, resources = plan_runner(log_config=log_config) - assert len(resources) == 4 - assert set(r['type'] for r in resources) == set([ - 'google_compute_firewall', 'time_static' - ]) - firewall_values = [r['values'] for r in resources if r['type'] - == 'google_compute_firewall'] - assert all(f['log_config'] == log_config_value for f in firewall_values) diff --git a/tests/blueprints/factories/project_factory/__init__.py b/tests/blueprints/factories/project_factory/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/factories/project_factory/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/factories/project_factory/examples/example.yaml b/tests/blueprints/factories/project_factory/examples/example.yaml new file mode 100644 index 0000000000..fe33a437d6 --- /dev/null +++ b/tests/blueprints/factories/project_factory/examples/example.yaml @@ -0,0 +1,235 @@ +# 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. + +# This is one of the few modules where it actually makes sense to be +# very verbose with values + +values: + module.projects["project"].google_compute_subnetwork_iam_member.default["dev-default-ew1:serviceAccount:my-service-account"]: + condition: [] + member: serviceAccount:my-service-account + project: fast-dev-net-spoke-0 + region: europe-west1 + role: roles/compute.networkUser + subnetwork: projects/fast-dev-net-spoke-0/regions/europe-west1/subnetworks/dev-default-ew1 + module.projects["project"].google_compute_subnetwork_iam_member.default["dev-default-ew1:user:foobar@example.com"]: + condition: [] + member: user:foobar@example.com + project: fast-dev-net-spoke-0 + region: europe-west1 + role: roles/compute.networkUser + subnetwork: projects/fast-dev-net-spoke-0/regions/europe-west1/subnetworks/dev-default-ew1 + module.projects["project"].module.billing-alert["1"].google_billing_budget.budget: + all_updates_rule: + - disable_default_iam_recipients: false + pubsub_topic: null + schema_version: '1.0' + amount: + - last_period_amount: null + specified_amount: + - nanos: null + units: '10' + billing_account: 012345-67890A-BCDEF0 + budget_filter: + - calendar_period: null + credit_types_treatment: INCLUDE_ALL_CREDITS + custom_period: [] + display_name: test1-project budget + threshold_rules: + - spend_basis: CURRENT_SPEND + threshold_percent: 0.5 + - spend_basis: CURRENT_SPEND + threshold_percent: 0.8 + module.projects["project"].module.billing-alert["1"].google_monitoring_notification_channel.email_channels["team-a-contacts@example.com"]: + display_name: test1-project budget budget email notification (team-a-contacts@example.com) + labels: + email_address: team-a-contacts@example.com + project: test1-project + sensitive_labels: [] + type: email + module.projects["project"].module.billing-alert["1"].google_monitoring_notification_channel.email_channels["team-contacts@example.com"]: + display_name: test1-project budget budget email notification (team-contacts@example.com) + labels: + email_address: team-contacts@example.com + project: test1-project + sensitive_labels: [] + type: email + module.projects["project"].module.dns["ipsum"].google_dns_managed_zone.non-public[0]: + dns_name: ipsum.dev.example.org + name: ipsum + private_visibility_config: + - gke_clusters: [] + networks: + - network_url: projects/foo/networks/bar + project: fast-dev-net-spoke-0 + visibility: private + module.projects["project"].module.dns["lorem"].google_dns_managed_zone.non-public[0]: + dns_name: lorem.dev.example.org + name: lorem + private_visibility_config: + - gke_clusters: [] + networks: + - network_url: projects/foo/networks/bar + project: fast-dev-net-spoke-0 + module.projects["project"].module.project.google_compute_shared_vpc_service_project.shared_vpc_service[0]: + host_project: fast-dev-net-spoke-0 + service_project: test1-project + module.projects["project"].module.project.google_essential_contacts_contact.contact["team-a-contacts@example.com"]: + email: team-a-contacts@example.com + language_tag: en + notification_category_subscriptions: + - ALL + parent: projects/test1-project + module.projects["project"].module.project.google_essential_contacts_contact.contact["team-contacts@example.com"]: + email: team-contacts@example.com + language_tag: en + notification_category_subscriptions: + - ALL + parent: projects/test1-project + module.projects["project"].module.project.google_org_policy_policy.default["compute.disableGuestAttributesAccess"]: + name: projects/test1-project/policies/compute.disableGuestAttributesAccess + parent: projects/test1-project + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + module.projects["project"].module.project.google_org_policy_policy.default["compute.trustedImageProjects"]: + name: projects/test1-project/policies/compute.trustedImageProjects + parent: projects/test1-project + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: + - projects/fast-dev-iac-core-0 + denied_values: null + module.projects["project"].module.project.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + name: projects/test1-project/policies/compute.vmExternalIpAccess + parent: projects/test1-project + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + values: [] + module.projects["project"].module.project.google_project.project[0]: + auto_create_network: false + billing_account: 012345-67890A-BCDEF0 + folder_id: 012345678901 + labels: + application: example-app + costcenter: apps + department: accounting + environment: dev + foo: bar + name: test1-project + org_id: null + project_id: test1-project + skip_delete: false + module.projects["project"].module.project.google_project_iam_binding.authoritative["roles/compute.admin"]: + condition: [] + project: test1-project + role: roles/compute.admin + module.projects["project"].module.project.google_project_iam_binding.authoritative["roles/compute.adminv1"]: + condition: [] + project: test1-project + role: roles/compute.adminv1 + module.projects["project"].module.project.google_project_iam_binding.authoritative["roles/storage.objectViewer"]: + condition: [] + project: test1-project + role: roles/storage.objectViewer + module.projects["project"].module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.networkUser:cloudservices"]: + condition: [] + project: fast-dev-net-spoke-0 + role: roles/compute.networkUser + module.projects["project"].module.project.google_project_iam_member.shared_vpc_host_robots["roles/compute.securityAdmin:container-engine"]: + condition: [] + project: fast-dev-net-spoke-0 + role: roles/compute.securityAdmin + module.projects["project"].module.project.google_project_service.project_services["billingbudgets.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: billingbudgets.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["compute.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: compute.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["container.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: container.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["dns.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: dns.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["essentialcontacts.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: essentialcontacts.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["orgpolicy.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: orgpolicy.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["stackdriver.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: stackdriver.googleapis.com + module.projects["project"].module.project.google_project_service.project_services["storage.googleapis.com"]: + disable_dependent_services: false + disable_on_destroy: false + project: test1-project + service: storage.googleapis.com + module.projects["project"].module.service-accounts["another-service-account"].google_service_account.service_account[0]: + account_id: another-service-account + display_name: Terraform-managed. + project: test1-project + module.projects["project"].module.service-accounts["my-service-account"].google_service_account.service_account[0]: + account_id: my-service-account + display_name: Terraform-managed. + project: test1-project + +counts: + google_billing_budget: 1 + google_compute_shared_vpc_service_project: 1 + google_compute_subnetwork_iam_member: 2 + google_dns_managed_zone: 2 + google_essential_contacts_contact: 2 + google_monitoring_notification_channel: 2 + google_org_policy_policy: 3 + google_project: 1 + google_project_iam_binding: 3 + google_project_iam_member: 2 + google_project_service: 8 + google_service_account: 2 + google_storage_project_service_account: 1 diff --git a/tests/blueprints/factories/project_factory/fixture/defaults.yaml b/tests/blueprints/factories/project_factory/fixture/defaults.yaml deleted file mode 100644 index 61837818f1..0000000000 --- a/tests/blueprints/factories/project_factory/fixture/defaults.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# skip boilerplate check - -billing_account_id: 012345-67890A-BCDEF0 - -# [opt] Setup for billing alerts -billing_alert: - amount: 1000 - thresholds: - current: [0.5, 0.8] - forecasted: [0.5, 0.8] - credit_treatment: INCLUDE_ALL_CREDITS - -# [opt] Contacts for billing alerts and important notifications -essential_contacts: ["team-contacts@example.com"] - -# [opt] Labels set for all projects -labels: - environment: prod - department: accounting - application: example-app - foo: bar - -# [opt] Additional notification channels for billing -notification_channels: [] -prefix: test diff --git a/tests/blueprints/factories/project_factory/fixture/main.tf b/tests/blueprints/factories/project_factory/fixture/main.tf deleted file mode 100644 index ae686b9350..0000000000 --- a/tests/blueprints/factories/project_factory/fixture/main.tf +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -locals { - _defaults = yamldecode(file(var.defaults_file)) - _defaults_net = { - billing_account_id = var.billing_account_id - environment_dns_zone = var.environment_dns_zone - shared_vpc_self_link = var.shared_vpc_self_link - vpc_host_project = var.vpc_host_project - } - defaults = merge(local._defaults, local._defaults_net) - projects = { - for f in fileset("${var.data_dir}", "**/*.yaml") : - trimsuffix(f, ".yaml") => yamldecode(file("${var.data_dir}/${f}")) - } -} - -module "projects" { - source = "../../../../../blueprints/factories/project-factory" - for_each = local.projects - defaults = local.defaults - project_id = each.key - billing_account_id = try(each.value.billing_account_id, null) - billing_alert = try(each.value.billing_alert, null) - dns_zones = try(each.value.dns_zones, []) - essential_contacts = try(each.value.essential_contacts, []) - folder_id = each.value.folder_id - group_iam = try(each.value.group_iam, {}) - iam = try(each.value.iam, {}) - kms_service_agents = try(each.value.kms, {}) - labels = try(each.value.labels, {}) - org_policies = try(each.value.org_policies, null) - prefix = each.value.prefix - service_accounts = try(each.value.service_accounts, {}) - services = try(each.value.services, []) - service_identities_iam = try(each.value.service_identities_iam, {}) - vpc = try(each.value.vpc, null) -} diff --git a/tests/blueprints/factories/project_factory/fixture/projects/project.yaml b/tests/blueprints/factories/project_factory/fixture/projects/project.yaml deleted file mode 100644 index a158198484..0000000000 --- a/tests/blueprints/factories/project_factory/fixture/projects/project.yaml +++ /dev/null @@ -1,104 +0,0 @@ -# skip boilerplate check - -# [opt] Billing account id - overrides default if set -billing_account_id: 012345-67890A-BCDEF0 - -# [opt] Billing alerts config - overrides default if set -billing_alert: - amount: 10 - thresholds: - current: - - 0.5 - - 0.8 - forecasted: [] - credit_treatment: INCLUDE_ALL_CREDITS - -# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults -dns_zones: - - lorem - - ipsum - -# [opt] Contacts for billing alerts and important notifications -essential_contacts: - - team-a-contacts@example.com - -# Folder the project will be created as children of -folder_id: folders/012345678901 - -# [opt] Authoritative IAM bindings in group => [roles] format -group_iam: - test-team-foobar@fast-lab-0.gcp-pso-italy.net: - - roles/compute.admin - -# [opt] Authoritative IAM bindings in role => [principals] format -# Generally used to grant roles to service accounts external to the project -iam: - roles/compute.admin: - - serviceAccount:service-account - -# [opt] Service robots and keys they will be assigned as cryptoKeyEncrypterDecrypter -# in service => [keys] format -kms_service_agents: - compute: [key1, key2] - storage: [key1, key2] - -# [opt] Labels for the project - merged with the ones defined in defaults -labels: - environment: prod - -# [opt] Org policy overrides defined at project level -org_policies: - policy_boolean: - constraints/compute.disableGuestAttributesAccess: true - policy_list: - constraints/compute.trustedImageProjects: - inherit_from_parent: null - status: true - suggested_value: null - values: - - projects/fast-prod-iac-core-0 - -# [opt] Prefix - overrides default if set -prefix: test1 - -# [opt] Service account to create for the project and their roles on the project -# in name => [roles] format -service_accounts: - another-service-account: - - roles/compute.admin - my-service-account: - - roles/compute.admin - -# [opt] APIs to enable on the project. -services: - - storage.googleapis.com - - stackdriver.googleapis.com - - compute.googleapis.com - -# [opt] Roles to assign to the service identities in service => [roles] format -service_identities_iam: - compute: - - roles/storage.objectViewer - - # [opt] VPC setup. - # If set enables the `compute.googleapis.com` service and configures - # service project attachment -vpc: - # [opt] If set, enables the container API - gke_setup: - # Grants "roles/container.hostServiceAgentUser" to the container robot if set - enable_host_service_agent: false - - # Grants "roles/compute.securityAdmin" to the container robot if set - enable_security_admin: true - - # Host project the project will be service project of - host_project: fast-prod-net-spoke-0 - - # [opt] Subnets in the host project where principals will be granted networkUser - # in region/subnet-name => [principals] - subnets_iam: - europe-west1/prod-default-ew1: - - user:foobar@example.com - - serviceAccount:service-account1@example.com - - my-service-account diff --git a/tests/blueprints/factories/project_factory/fixture/variables.tf b/tests/blueprints/factories/project_factory/fixture/variables.tf deleted file mode 100644 index d0d6759bad..0000000000 --- a/tests/blueprints/factories/project_factory/fixture/variables.tf +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2022 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. - */ - -variable "billing_account_id" { - description = "Billing account id." - type = string - default = "012345-67890A-BCDEF0" -} - -variable "data_dir" { - description = "Relative path for the folder storing configuration data." - type = string - default = "./projects/" -} - -variable "environment_dns_zone" { - description = "DNS zone suffix for environment." - type = string - default = "prod.gcp.example.com" -} - -variable "defaults_file" { - description = "Relative path for the file storing the project factory configuration." - type = string - default = "./defaults.yaml" -} - -variable "service_accounts" { - description = "Service accounts to be created, and roles assigned them on the project." - type = map(list(string)) - default = {} -} - -variable "service_accounts_iam" { - description = "IAM bindings on service account resources. Format is KEY => {ROLE => [MEMBERS]}" - type = map(map(list(string))) - default = {} - nullable = false -} - -variable "shared_vpc_self_link" { - description = "Self link for the shared VPC." - type = string - default = "self-link" -} - -variable "vpc_host_project" { - description = "Host project for the shared VPC." - type = string - default = "host-project" -} diff --git a/tests/blueprints/factories/project_factory/test_plan.py b/tests/blueprints/factories/project_factory/test_plan.py deleted file mode 100644 index 4c8e86412c..0000000000 --- a/tests/blueprints/factories/project_factory/test_plan.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright 2022 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. - - -def test_plan(e2e_plan_runner): - "Check for a clean plan" - modules, resources = e2e_plan_runner() - assert len(modules) > 0 and len(resources) > 0 - - -def test_plan_service_accounts(e2e_plan_runner): - "Check for a clean plan" - service_accounts = '''{ - sa-001 = [] - sa-002 = ["roles/owner"] - }''' - service_accounts_iam = '''{ - sa-002 = { - "roles/iam.serviceAccountTokenCreator" = ["group:team-1@example.com"] - } - }''' - modules, resources = e2e_plan_runner( - service_accounts=service_accounts, - service_accounts_iam=service_accounts_iam) - assert len(modules) > 0 and len(resources) > 0 diff --git a/tests/blueprints/gke/__init__.py b/tests/blueprints/gke/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/gke/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/gke/binauthz/__init__.py b/tests/blueprints/gke/binauthz/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/gke/binauthz/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/gke/binauthz/fixture/main.tf b/tests/blueprints/gke/binauthz/fixture/main.tf deleted file mode 100644 index 23e1504b84..0000000000 --- a/tests/blueprints/gke/binauthz/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/gke/binauthz" - prefix = var.prefix - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/gke/binauthz/fixture/variables.tf b/tests/blueprints/gke/binauthz/fixture/variables.tf deleted file mode 100644 index 8a09c75eba..0000000000 --- a/tests/blueprints/gke/binauthz/fixture/variables.tf +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "12345-12345-12345" - parent = "folders/123456789" - } -} - -variable "project_id" { - type = string - default = "my-project" -} - -variable "prefix" { - type = string - default = "test" -} diff --git a/tests/blueprints/gke/binauthz/test_plan.py b/tests/blueprints/gke/binauthz/test_plan.py deleted file mode 100644 index b4437b6f3d..0000000000 --- a/tests/blueprints/gke/binauthz/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 13 - assert len(resources) == 44 diff --git a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/__init__.py b/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/fixture/main.tf b/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/fixture/main.tf deleted file mode 100644 index 47524fa526..0000000000 --- a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/fixture/main.tf +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/gke/multi-cluster-mesh-gke-fleet-api" - billing_account_id = var.billing_account_id - parent = var.parent - host_project_id = var.host_project_id - fleet_project_id = var.fleet_project_id - mgmt_project_id = var.mgmt_project_id - region = var.region - clusters_config = var.clusters_config - mgmt_subnet_cidr_block = var.mgmt_subnet_cidr_block - istio_version = var.istio_version -} diff --git a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/fixture/variables.tf b/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/fixture/variables.tf deleted file mode 100644 index 6c6b6c8fba..0000000000 --- a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/fixture/variables.tf +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright 2022 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. - */ - -variable "billing_account_id" { - description = "Billing account id." - type = string - default = "123-456-789" -} - -variable "parent" { - description = "Parent." - type = string - default = "folders/123456789" -} - -variable "host_project_id" { - description = "Host project ID." - type = string - default = "my-host-project" -} - -variable "fleet_project_id" { - description = "Fleet project ID." - type = string - default = "my-fleet-project" -} - -variable "mgmt_project_id" { - description = "Management Project ID." - type = string - default = "my-mgmt-project" -} - -variable "mgmt_subnet_cidr_block" { - description = "Management subnet CIDR block." - type = string - default = "10.0.0.0/24" -} - -variable "region" { - description = "Region." - type = string - default = "europe-west1" -} - -variable "clusters_config" { - description = "Clusters configuration." - type = map(object({ - subnet_cidr_block = string - master_cidr_block = string - services_cidr_block = string - pods_cidr_block = string - })) - default = { - cluster-a = { - subnet_cidr_block = "10.0.1.0/24" - master_cidr_block = "10.16.0.0/28" - services_cidr_block = "192.168.1.0/24" - pods_cidr_block = "172.16.0.0/20" - } - cluster-b = { - subnet_cidr_block = "10.0.2.0/24" - master_cidr_block = "10.16.0.16/28" - services_cidr_block = "192.168.2.0/24" - pods_cidr_block = "172.16.16.0/20" - } - } -} - -variable "mgmt_server_config" { - description = "Mgmt server configuration" - type = object({ - disk_size = number - disk_type = string - image = string - instance_type = string - region = string - zone = string - }) - default = { - disk_size = 50 - disk_type = "pd-ssd" - image = "projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts" - instance_type = "n1-standard-2" - region = "europe-west1" - zone = "europe-west1-c" - } -} - -variable "istio_version" { - description = "ASM version" - type = string - default = "1.14.1-asm.3" -} diff --git a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/test_plan.py b/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/test_plan.py deleted file mode 100644 index 2379849dcc..0000000000 --- a/tests/blueprints/gke/multi_cluster_mesh_gke_fleet_api/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 12 - assert len(resources) == 55 diff --git a/tests/blueprints/gke/multitenant_fleet/__init__.py b/tests/blueprints/gke/multitenant_fleet/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/gke/multitenant_fleet/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/gke/multitenant_fleet/fixture/main.tf b/tests/blueprints/gke/multitenant_fleet/fixture/main.tf deleted file mode 100644 index 394d555de3..0000000000 --- a/tests/blueprints/gke/multitenant_fleet/fixture/main.tf +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/gke/multitenant-fleet" - project_id = "test-prj" - billing_account_id = "ABCDEF-0123456-ABCDEF" - folder_id = "folders/1234567890" - prefix = "test" - clusters = { - cluster-0 = { - location = "europe-west1" - private_cluster_config = { - enable_private_endpoint = true - master_global_access = true - } - vpc_config = { - subnetwork = "projects/my-host-project-id/regions/europe-west1/subnetworks/mycluster-subnet" - master_ipv4_cidr_block = "172.16.10.0/28" - secondary_range_names = { - pods = "pods" - services = "services" - } - } - } - } - nodepools = { - cluster-0 = { - nodepool-0 = { - node_config = { - disk_type = "pd-balanced" - machine_type = "n2-standard-4" - spot = true - } - } - } - } - vpc_config = { - host_project_id = "my-host-project-id" - vpc_self_link = "projects/my-host-project-id/global/networks/my-network" - } -} diff --git a/tests/blueprints/gke/multitenant_fleet/test_plan.py b/tests/blueprints/gke/multitenant_fleet/test_plan.py deleted file mode 100644 index c8a8369496..0000000000 --- a/tests/blueprints/gke/multitenant_fleet/test_plan.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2022 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. - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 4 - assert len(resources) == 23 diff --git a/tests/blueprints/gke/shared_vpc_gke/__init__.py b/tests/blueprints/gke/shared_vpc_gke/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/gke/shared_vpc_gke/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/gke/shared_vpc_gke/fixture/main.tf b/tests/blueprints/gke/shared_vpc_gke/fixture/main.tf deleted file mode 100644 index ac4e647a2e..0000000000 --- a/tests/blueprints/gke/shared_vpc_gke/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/gke/shared-vpc-gke" - billing_account_id = var.billing_account_id - prefix = var.prefix - root_node = var.root_node -} diff --git a/tests/blueprints/gke/shared_vpc_gke/fixture/variables.tf b/tests/blueprints/gke/shared_vpc_gke/fixture/variables.tf deleted file mode 100644 index 59933f9aad..0000000000 --- a/tests/blueprints/gke/shared_vpc_gke/fixture/variables.tf +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "billing_account_id" { - type = string - default = "ABCDE-12345-ABCDE" -} - -variable "prefix" { - type = string - default = "test" -} - -variable "root_node" { - type = string - default = "organizations/0123456789" -} diff --git a/tests/blueprints/gke/shared_vpc_gke/test_plan.py b/tests/blueprints/gke/shared_vpc_gke/test_plan.py deleted file mode 100644 index 8d0f6bd617..0000000000 --- a/tests/blueprints/gke/shared_vpc_gke/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 10 - assert len(resources) == 43 diff --git a/tests/blueprints/networking/decentralized_firewall/__init__.py b/tests/blueprints/networking/decentralized_firewall/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/decentralized_firewall/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/decentralized_firewall/fixture/main.tf b/tests/blueprints/networking/decentralized_firewall/fixture/main.tf deleted file mode 100644 index 92d45041ec..0000000000 --- a/tests/blueprints/networking/decentralized_firewall/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/decentralized-firewall" - billing_account_id = var.billing_account_id - prefix = var.prefix - root_node = var.root_node -} diff --git a/tests/blueprints/networking/decentralized_firewall/fixture/variables.tf b/tests/blueprints/networking/decentralized_firewall/fixture/variables.tf deleted file mode 100644 index 59933f9aad..0000000000 --- a/tests/blueprints/networking/decentralized_firewall/fixture/variables.tf +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "billing_account_id" { - type = string - default = "ABCDE-12345-ABCDE" -} - -variable "prefix" { - type = string - default = "test" -} - -variable "root_node" { - type = string - default = "organizations/0123456789" -} diff --git a/tests/blueprints/networking/decentralized_firewall/test_plan.py b/tests/blueprints/networking/decentralized_firewall/test_plan.py deleted file mode 100644 index 885b9b3871..0000000000 --- a/tests/blueprints/networking/decentralized_firewall/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 8 - assert len(resources) == 50 diff --git a/tests/blueprints/networking/filtering_proxy/__init__.py b/tests/blueprints/networking/filtering_proxy/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/filtering_proxy/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/filtering_proxy/fixture/main.tf b/tests/blueprints/networking/filtering_proxy/fixture/main.tf deleted file mode 100644 index 2d250c0abd..0000000000 --- a/tests/blueprints/networking/filtering_proxy/fixture/main.tf +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/filtering-proxy" - billing_account = "123456-123456-123456" - mig = var.mig - prefix = "fabric" - root_node = "folders/123456789" -} diff --git a/tests/blueprints/networking/filtering_proxy/test_plan.py b/tests/blueprints/networking/filtering_proxy/test_plan.py deleted file mode 100644 index c13a5d1aa0..0000000000 --- a/tests/blueprints/networking/filtering_proxy/test_plan.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 11 - assert len(resources) == 30 - - modules, resources = e2e_plan_runner(mig="true") - assert len(modules) == 13 - assert len(resources) == 36 diff --git a/tests/blueprints/networking/filtering_proxy_psc/__init__.py b/tests/blueprints/networking/filtering_proxy_psc/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/filtering_proxy_psc/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/filtering_proxy_psc/fixture/main.tf b/tests/blueprints/networking/filtering_proxy_psc/fixture/main.tf deleted file mode 100644 index eb01058d10..0000000000 --- a/tests/blueprints/networking/filtering_proxy_psc/fixture/main.tf +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/filtering-proxy-psc" - prefix = "fabric" - project_create = { - billing_account = "123456-ABCDEF-123456" - parent = "folders/1234567890" - } - project_id = "test-project" -} diff --git a/tests/blueprints/networking/filtering_proxy_psc/test_plan.py b/tests/blueprints/networking/filtering_proxy_psc/test_plan.py deleted file mode 100644 index 498bb2bfb5..0000000000 --- a/tests/blueprints/networking/filtering_proxy_psc/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 12 - assert len(resources) == 34 diff --git a/tests/blueprints/networking/glb_and_armor/__init__.py b/tests/blueprints/networking/glb_and_armor/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/glb_and_armor/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/glb_and_armor/fixture/main.tf b/tests/blueprints/networking/glb_and_armor/fixture/main.tf deleted file mode 100644 index 2a5a70773f..0000000000 --- a/tests/blueprints/networking/glb_and_armor/fixture/main.tf +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -module "test" { - source = "../../../../../blueprints/networking/glb-and-armor" - prefix = var.prefix - project_create = var.project_create - project_id = var.project_id - enforce_security_policy = var.enforce_security_policy -} diff --git a/tests/blueprints/networking/glb_and_armor/fixture/variables.tf b/tests/blueprints/networking/glb_and_armor/fixture/variables.tf deleted file mode 100644 index 41090c1c32..0000000000 --- a/tests/blueprints/networking/glb_and_armor/fixture/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "prefix" { - type = string - default = "test" -} - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "123456789" - parent = "organizations/123456789" - } -} - -variable "project_id" { - type = string - default = "project-1" -} - -variable "enforce_security_policy" { - type = bool - default = true -} diff --git a/tests/blueprints/networking/glb_and_armor/test_plan.py b/tests/blueprints/networking/glb_and_armor/test_plan.py deleted file mode 100644 index dc4a4956ff..0000000000 --- a/tests/blueprints/networking/glb_and_armor/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 11 - assert len(resources) == 25 diff --git a/tests/blueprints/networking/hub_and_spoke_peering/__init__.py b/tests/blueprints/networking/hub_and_spoke_peering/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_peering/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/hub_and_spoke_peering/fixture/main.tf b/tests/blueprints/networking/hub_and_spoke_peering/fixture/main.tf deleted file mode 100644 index c5b105e68a..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_peering/fixture/main.tf +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/hub-and-spoke-peering" - prefix = var.prefix - project_create = { - billing_account = "123456-123456-123456" - oslogin = true - parent = "folders/123456789" - } - project_id = var.project_id -} diff --git a/tests/blueprints/networking/hub_and_spoke_peering/fixture/variables.tf b/tests/blueprints/networking/hub_and_spoke_peering/fixture/variables.tf deleted file mode 100644 index b67795f96e..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_peering/fixture/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "prefix" { - type = string - default = "test" -} - -variable "project_id" { - type = string - default = "project-1" -} diff --git a/tests/blueprints/networking/hub_and_spoke_peering/test_plan.py b/tests/blueprints/networking/hub_and_spoke_peering/test_plan.py deleted file mode 100644 index 127a0ba4ba..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_peering/test_plan.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2022 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. - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 21 - assert len(resources) == 61 diff --git a/tests/blueprints/networking/hub_and_spoke_vpn/__init__.py b/tests/blueprints/networking/hub_and_spoke_vpn/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_vpn/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/hub_and_spoke_vpn/fixture/main.tf b/tests/blueprints/networking/hub_and_spoke_vpn/fixture/main.tf deleted file mode 100644 index 37558c7145..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_vpn/fixture/main.tf +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/hub-and-spoke-vpn" - prefix = var.prefix - project_create_config = { - billing_account_id = "ABCDE-123456-ABCDE" - parent_id = null - } - project_id = var.project_id -} diff --git a/tests/blueprints/networking/hub_and_spoke_vpn/fixture/variables.tf b/tests/blueprints/networking/hub_and_spoke_vpn/fixture/variables.tf deleted file mode 100644 index b67795f96e..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_vpn/fixture/variables.tf +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "prefix" { - type = string - default = "test" -} - -variable "project_id" { - type = string - default = "project-1" -} diff --git a/tests/blueprints/networking/hub_and_spoke_vpn/test_plan.py b/tests/blueprints/networking/hub_and_spoke_vpn/test_plan.py deleted file mode 100644 index a24aaa596b..0000000000 --- a/tests/blueprints/networking/hub_and_spoke_vpn/test_plan.py +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright 2022 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. - - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 19 - assert len(resources) == 73 diff --git a/tests/blueprints/networking/ilb_next_hop/__init__.py b/tests/blueprints/networking/ilb_next_hop/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/ilb_next_hop/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/ilb_next_hop/fixture/main.tf b/tests/blueprints/networking/ilb_next_hop/fixture/main.tf deleted file mode 100644 index acaad22ad4..0000000000 --- a/tests/blueprints/networking/ilb_next_hop/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/ilb-next-hop" - prefix = var.prefix - project_create = var.project_create - project_id = var.project_id -} diff --git a/tests/blueprints/networking/ilb_next_hop/fixture/variables.tf b/tests/blueprints/networking/ilb_next_hop/fixture/variables.tf deleted file mode 100644 index 4eede1798a..0000000000 --- a/tests/blueprints/networking/ilb_next_hop/fixture/variables.tf +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2022 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 -# -# https://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. - -variable "prefix" { - type = string - default = "test" -} - -variable "project_create" { - type = bool - default = true -} - -variable "project_id" { - type = string - default = "project-1" -} diff --git a/tests/blueprints/networking/ilb_next_hop/test_plan.py b/tests/blueprints/networking/ilb_next_hop/test_plan.py deleted file mode 100644 index d2419ddfc2..0000000000 --- a/tests/blueprints/networking/ilb_next_hop/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 17 - assert len(resources) == 42 diff --git a/tests/blueprints/networking/private_cloud_function_from_onprem/__init__.py b/tests/blueprints/networking/private_cloud_function_from_onprem/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/networking/private_cloud_function_from_onprem/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/networking/private_cloud_function_from_onprem/fixture/main.tf b/tests/blueprints/networking/private_cloud_function_from_onprem/fixture/main.tf deleted file mode 100644 index d166a0fc28..0000000000 --- a/tests/blueprints/networking/private_cloud_function_from_onprem/fixture/main.tf +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/networking/private-cloud-function-from-onprem" - project_create = { - billing_account_id = "123456-ABCDEF-123456" - parent = "folders/1234567890" - } - project_id = "test-project" -} diff --git a/tests/blueprints/networking/private_cloud_function_from_onprem/test_plan.py b/tests/blueprints/networking/private_cloud_function_from_onprem/test_plan.py deleted file mode 100644 index 81225db364..0000000000 --- a/tests/blueprints/networking/private_cloud_function_from_onprem/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 10 - assert len(resources) == 39 diff --git a/tests/blueprints/serverless/__init__.py b/tests/blueprints/serverless/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/serverless/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/serverless/api_gateway/__init__.py b/tests/blueprints/serverless/api_gateway/__init__.py deleted file mode 100644 index 6d6d1266c3..0000000000 --- a/tests/blueprints/serverless/api_gateway/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2022 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. diff --git a/tests/blueprints/serverless/api_gateway/fixture/main.tf b/tests/blueprints/serverless/api_gateway/fixture/main.tf deleted file mode 100644 index 094d469773..0000000000 --- a/tests/blueprints/serverless/api_gateway/fixture/main.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2022 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. - */ - -module "test" { - source = "../../../../../blueprints/serverless/api-gateway" - project_create = var.project_create - project_id = var.project_id - regions = var.regions -} diff --git a/tests/blueprints/serverless/api_gateway/fixture/variables.tf b/tests/blueprints/serverless/api_gateway/fixture/variables.tf deleted file mode 100644 index dce1579cd4..0000000000 --- a/tests/blueprints/serverless/api_gateway/fixture/variables.tf +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright 2022 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. - */ - -variable "project_create" { - type = object({ - billing_account_id = string - parent = string - }) - default = { - billing_account_id = "123456789" - parent = "organizations/123456789" - } -} - -variable "project_id" { - type = string - default = "project-1" -} - -variable "regions" { - type = list(string) - default = [ - "europe-west1", - "europe-west2" - ] -} diff --git a/tests/blueprints/serverless/api_gateway/test_plan.py b/tests/blueprints/serverless/api_gateway/test_plan.py deleted file mode 100644 index 9d658398ec..0000000000 --- a/tests/blueprints/serverless/api_gateway/test_plan.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2022 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. - -def test_resources(e2e_plan_runner): - "Test that plan works and the numbers of resources is as expected." - modules, resources = e2e_plan_runner() - assert len(modules) == 7 - assert len(resources) == 32 diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml b/tests/blueprints/test_empty.py similarity index 73% rename from tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml rename to tests/blueprints/test_empty.py index 5c92fb82ae..9afb6366f1 100644 --- a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml +++ b/tests/blueprints/test_empty.py @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -12,7 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -module: blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg -tests: - basic: +def test_dummy(): + """ + Blueprint tests are mostly run from READMEs now. Leave an empty + test so pipelines don't fail because of an empty test suite + """ + assert True diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py index 261276f737..b12d82fcef 100644 --- a/tests/examples/test_plan.py +++ b/tests/examples/test_plan.py @@ -18,7 +18,7 @@ BASE_PATH = Path(__file__).parent COUNT_TEST_RE = re.compile(r'# tftest +modules=(\d+) +resources=(\d+)' + - r'(?: +files=([\w,_-]+))?' + + r'(?: +files=([\w@,_-]+))?' + r'(?: +inventory=([\w\-.]+))?') diff --git a/tests/fast/stages/s3_project_factory/data/projects/project.yaml b/tests/fast/stages/s3_project_factory/data/projects/project.yaml index d988d9d50c..90354a2ac7 100644 --- a/tests/fast/stages/s3_project_factory/data/projects/project.yaml +++ b/tests/fast/stages/s3_project_factory/data/projects/project.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -60,15 +60,14 @@ labels: # [opt] Org policy overrides defined at project level org_policies: - policy_boolean: - constraints/compute.disableGuestAttributesAccess: true - policy_list: - constraints/compute.trustedImageProjects: - inherit_from_parent: null - status: true - suggested_value: null - values: - - projects/fast-prod-iac-core-0 + compute.disableGuestAttributesAccess: + rules: + - enforce: true + compute.trustedImageProjects: + rules: + - allow: + values: + - projects/fast-prod-iac-core-0 # [opt] Service account to create for the project and their roles on the project # in name => [roles] format diff --git a/tests/modules/compute_vm/examples/cmek.yaml b/tests/modules/compute_vm/examples/cmek.yaml index cf390fde0a..403825bc65 100644 --- a/tests/modules/compute_vm/examples/cmek.yaml +++ b/tests/modules/compute_vm/examples/cmek.yaml @@ -18,6 +18,7 @@ values: - kms_key_self_link: kms_key_self_link kms_key_service_account: null raw_key: null + rsa_encrypted_key: null labels: disk_name: attached-disk disk_type: pd-balanced diff --git a/tests/modules/folder/examples/org-policies.yaml b/tests/modules/folder/examples/org-policies.yaml index f8bf41879a..c7bee1239e 100644 --- a/tests/modules/folder/examples/org-policies.yaml +++ b/tests/modules/folder/examples/org-policies.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -26,7 +26,7 @@ values: deny_all: null enforce: 'TRUE' values: [] - module.folder.google_org_policy_policy.default["constraints/compute.skipDefaultNetworkCreation"]: + module.folder.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: spec: - inherit_from_parent: null reset: null @@ -36,7 +36,7 @@ values: deny_all: null enforce: 'TRUE' values: [] - module.folder.google_org_policy_policy.default["constraints/compute.trustedImageProjects"]: + module.folder.google_org_policy_policy.default["compute.trustedImageProjects"]: spec: - inherit_from_parent: null reset: null @@ -49,7 +49,7 @@ values: - allowed_values: - projects/my-project denied_values: null - module.folder.google_org_policy_policy.default["constraints/compute.vmExternalIpAccess"]: + module.folder.google_org_policy_policy.default["compute.vmExternalIpAccess"]: spec: - inherit_from_parent: null reset: null @@ -59,7 +59,7 @@ values: deny_all: 'TRUE' enforce: null values: [] - module.folder.google_org_policy_policy.default["constraints/iam.allowedPolicyMemberDomains"]: + module.folder.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: spec: - inherit_from_parent: null reset: null @@ -91,7 +91,7 @@ values: - allow_all: null condition: - description: test condition - expression: resource.matchTagId("tagKeys/1234", "tagValues/1234") + expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234') location: somewhere title: condition deny_all: null diff --git a/tests/modules/folder/org_policies_boolean.tfvars b/tests/modules/folder/org_policies_boolean.tfvars index eceafe6d29..cf5047a205 100644 --- a/tests/modules/folder/org_policies_boolean.tfvars +++ b/tests/modules/folder/org_policies_boolean.tfvars @@ -1,9 +1,8 @@ org_policies = { "iam.disableServiceAccountKeyCreation" = { - enforce = true + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyUpload" = { - enforce = false rules = [ { condition = { @@ -13,6 +12,9 @@ org_policies = { location = "xxx" } enforce = true + }, + { + enforce = false } ] } diff --git a/tests/modules/folder/org_policies_list.tfvars b/tests/modules/folder/org_policies_list.tfvars index 7380717336..2c83de47e3 100644 --- a/tests/modules/folder/org_policies_list.tfvars +++ b/tests/modules/folder/org_policies_list.tfvars @@ -1,14 +1,15 @@ org_policies = { "compute.vmExternalIpAccess" = { - deny = { all = true } + rules = [{ deny = { all = true } }] } "iam.allowedPolicyMemberDomains" = { - allow = { - values = ["C0xxxxxxx", "C0yyyyyyy"] - } + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] } "compute.restrictLoadBalancerCreationForTypes" = { - deny = { values = ["in:EXTERNAL"] } rules = [ { condition = { @@ -31,6 +32,9 @@ org_policies = { allow = { all = true } + }, + { + deny = { values = ["in:EXTERNAL"] } } ] } diff --git a/tests/modules/gke_hub/test_plan.py b/tests/modules/gke_hub/test_plan.py index 8a71d12b57..3b847e397f 100644 --- a/tests/modules/gke_hub/test_plan.py +++ b/tests/modules/gke_hub/test_plan.py @@ -74,7 +74,7 @@ def test_configmanagement_setup(resources): membership_key = f'module.hub.google_gke_hub_membership.default["{cluster}"]' membership = resources[membership_key] link = membership['endpoint'][0]['gke_cluster'][0]['resource_link'] - assert link == f'projects/myproject/locations/europe-west1-b/clusters/{cluster}' + assert link == f'//container.googleapis.com/projects/myproject/locations/europe-west1-b/clusters/{cluster}' fm_key = f'module.hub.google_gke_hub_feature_membership.default["{cluster}"]' fm = resources[fm_key] diff --git a/tests/modules/net_vpc/examples/factory.yaml b/tests/modules/net_vpc/examples/factory.yaml index 48671c2922..0724b5970e 100644 --- a/tests/modules/net_vpc/examples/factory.yaml +++ b/tests/modules/net_vpc/examples/factory.yaml @@ -44,7 +44,18 @@ values: region: europe-west4 role: null secondary_ip_range: [] + module.vpc.google_compute_subnetwork_iam_binding.binding["europe-west1/subnet-detailed.roles/compute.networkUser"]: + condition: [] + members: + - group:lorem@example.com + - serviceAccount:fbz@prj.iam.gserviceaccount.com + - user:foobar@example.com + project: my-project + region: europe-west1 + role: roles/compute.networkUser + subnetwork: subnet-detailed counts: google_compute_network: 1 google_compute_subnetwork: 2 + google_compute_subnetwork_iam_binding: 1 diff --git a/tests/modules/net_vpc/examples/shared-vpc.yaml b/tests/modules/net_vpc/examples/shared-vpc.yaml index b004e31511..6467fd389e 100644 --- a/tests/modules/net_vpc/examples/shared-vpc.yaml +++ b/tests/modules/net_vpc/examples/shared-vpc.yaml @@ -24,7 +24,12 @@ values: module.vpc-host.google_compute_shared_vpc_service_project.service_projects["project2"]: host_project: my-project service_project: project2 - module.vpc-host.google_compute_subnetwork.subnetwork["europe-west1/subnet-1"]: {} + module.vpc-host.google_compute_subnetwork.subnetwork["europe-west1/subnet-1"]: + secondary_ip_range: + - ip_cidr_range: 172.16.0.0/20 + range_name: pods + - ip_cidr_range: 192.168.0.0/24 + range_name: services module.vpc-host.google_compute_subnetwork_iam_binding.binding["europe-west1/subnet-1.roles/compute.networkUser"]: condition: [] members: diff --git a/tests/modules/organization/examples/basic.yaml b/tests/modules/organization/examples/basic.yaml index f7b63a1d41..9960a71297 100644 --- a/tests/modules/organization/examples/basic.yaml +++ b/tests/modules/organization/examples/basic.yaml @@ -25,8 +25,8 @@ values: deny_all: null enforce: 'TRUE' values: [] - module.org.google_org_policy_policy.default["constraints/compute.skipDefaultNetworkCreation"]: - name: organizations/1234567890/policies/constraints/compute.skipDefaultNetworkCreation + module.org.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: + name: organizations/1234567890/policies/compute.skipDefaultNetworkCreation parent: organizations/1234567890 spec: - inherit_from_parent: null @@ -37,8 +37,8 @@ values: deny_all: null enforce: 'TRUE' values: [] - module.org.google_org_policy_policy.default["constraints/compute.trustedImageProjects"]: - name: organizations/1234567890/policies/constraints/compute.trustedImageProjects + module.org.google_org_policy_policy.default["compute.trustedImageProjects"]: + name: organizations/1234567890/policies/compute.trustedImageProjects parent: organizations/1234567890 spec: - inherit_from_parent: null @@ -52,8 +52,8 @@ values: - allowed_values: - projects/my-project denied_values: null - module.org.google_org_policy_policy.default["constraints/compute.vmExternalIpAccess"]: - name: organizations/1234567890/policies/constraints/compute.vmExternalIpAccess + module.org.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + name: organizations/1234567890/policies/compute.vmExternalIpAccess parent: organizations/1234567890 spec: - inherit_from_parent: null @@ -64,15 +64,30 @@ values: deny_all: 'TRUE' enforce: null values: [] - module.org.google_org_policy_policy.default["constraints/iam.allowedPolicyMemberDomains"]: - name: organizations/1234567890/policies/constraints/iam.allowedPolicyMemberDomains + module.org.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: + name: organizations/1234567890/policies/iam.allowedPolicyMemberDomains parent: organizations/1234567890 spec: - inherit_from_parent: null reset: null rules: + - allow_all: 'TRUE' + condition: + - description: Allow external identities when resource has the `allowexternal` + tag set to true. + expression: resource.matchTag('1234567890/allowexternal', 'true') + location: null + title: Allow external identities + deny_all: null + enforce: null + values: [] - allow_all: null - condition: [] + condition: + - description: For any resource without allowexternal=true, only allow identities + from restricted domains. + expression: '!resource.matchTag(''1234567890/allowexternal'', ''true'')' + location: null + title: '' deny_all: null enforce: null values: @@ -102,7 +117,7 @@ values: - allow_all: null condition: - description: test condition - expression: resource.matchTagId("tagKeys/1234", "tagValues/1234") + expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234') location: somewhere title: condition deny_all: null @@ -141,6 +156,20 @@ values: member: user:compute@example.org org_id: '1234567890' role: roles/container.viewer + module.org.google_tags_tag_key.default["allowexternal"]: + description: Allow external identities. + parent: organizations/1234567890 + purpose: null + purpose_data: null + short_name: allowexternal + module.org.google_tags_tag_value.default["allowexternal/false"]: + short_name: 'false' + module.org.google_tags_tag_value.default["allowexternal/true"]: + short_name: 'true' + counts: google_org_policy_policy: 8 google_organization_iam_binding: 3 + google_organization_iam_member: 2 + google_tags_tag_key: 1 + google_tags_tag_value: 2 diff --git a/tests/modules/organization/org_policies_boolean.tfvars b/tests/modules/organization/org_policies_boolean.tfvars index eceafe6d29..cf5047a205 100644 --- a/tests/modules/organization/org_policies_boolean.tfvars +++ b/tests/modules/organization/org_policies_boolean.tfvars @@ -1,9 +1,8 @@ org_policies = { "iam.disableServiceAccountKeyCreation" = { - enforce = true + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyUpload" = { - enforce = false rules = [ { condition = { @@ -13,6 +12,9 @@ org_policies = { location = "xxx" } enforce = true + }, + { + enforce = false } ] } diff --git a/tests/modules/organization/org_policies_list.tfvars b/tests/modules/organization/org_policies_list.tfvars index f9de8dbabe..d03f8530f1 100644 --- a/tests/modules/organization/org_policies_list.tfvars +++ b/tests/modules/organization/org_policies_list.tfvars @@ -1,15 +1,17 @@ org_policies = { "compute.vmExternalIpAccess" = { - deny = { all = true } + rules = [{ deny = { all = true } }] } "iam.allowedPolicyMemberDomains" = { inherit_from_parent = true - allow = { - values = ["C0xxxxxxx", "C0yyyyyyy"] - } + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] + } "compute.restrictLoadBalancerCreationForTypes" = { - deny = { values = ["in:EXTERNAL"] } rules = [ { condition = { @@ -32,6 +34,9 @@ org_policies = { allow = { all = true } + }, + { + deny = { values = ["in:EXTERNAL"] } } ] } diff --git a/tests/modules/organization/test_plan_org_policies_modules.py b/tests/modules/organization/test_plan_org_policies_modules.py index 1d19ee1eb6..30881d993e 100644 --- a/tests/modules/organization/test_plan_org_policies_modules.py +++ b/tests/modules/organization/test_plan_org_policies_modules.py @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -26,61 +26,35 @@ def test_policy_implementation(): path = modules_path / module / 'organization-policies.tf' lines[module] = path.open().readlines() - diff1 = difflib.unified_diff(lines['project'], lines['folder']) + diff1 = difflib.unified_diff(lines['project'], lines['folder'], 'project', + 'folder', n=0) assert list(diff1) == [ - '--- \n', - '+++ \n', - '@@ -14,7 +14,7 @@\n', - ' * limitations under the License.\n', - ' */\n', - ' \n', + '--- project\n', + '+++ folder\n', + '@@ -17 +17 @@\n', '-# tfdoc:file:description Project-level organization policies.\n', '+# tfdoc:file:description Folder-level organization policies.\n', - ' \n', - ' locals {\n', - ' _factory_data_raw = merge([\n', - '@@ -65,8 +65,8 @@\n', - ' org_policies = {\n', - ' for k, v in local._org_policies :\n', - ' k => merge(v, {\n', + '@@ -58,2 +58,2 @@\n', '- name = "projects/${local.project.project_id}/policies/${k}"\n', '- parent = "projects/${local.project.project_id}"\n', '+ name = "${local.folder.name}/policies/${k}"\n', '+ parent = local.folder.name\n', - ' \n', - ' is_boolean_policy = v.allow == null && v.deny == null\n', - ' has_values = (\n', ] - diff2 = difflib.unified_diff(lines['folder'], lines['organization']) + diff2 = difflib.unified_diff(lines['folder'], lines['organization'], 'folder', + 'organization', n=0) assert list(diff2) == [ - '--- \n', - '+++ \n', - '@@ -14,7 +14,7 @@\n', - ' * limitations under the License.\n', - ' */\n', - ' \n', + '--- folder\n', + '+++ organization\n', + '@@ -17 +17 @@\n', '-# tfdoc:file:description Folder-level organization policies.\n', '+# tfdoc:file:description Organization-level organization policies.\n', - ' \n', - ' locals {\n', - ' _factory_data_raw = merge([\n', - '@@ -65,8 +65,8 @@\n', - ' org_policies = {\n', - ' for k, v in local._org_policies :\n', - ' k => merge(v, {\n', + '@@ -58,2 +58,2 @@\n', '- name = "${local.folder.name}/policies/${k}"\n', '- parent = local.folder.name\n', '+ name = "${var.organization_id}/policies/${k}"\n', '+ parent = var.organization_id\n', - ' \n', - ' is_boolean_policy = v.allow == null && v.deny == null\n', - ' has_values = (\n', - '@@ -139,4 +139,13 @@\n', - ' }\n', - ' }\n', - ' }\n', - '+\n', + '@@ -116,0 +117,8 @@\n', '+ depends_on = [\n', '+ google_organization_iam_audit_config.config,\n', '+ google_organization_iam_binding.authoritative,\n', @@ -89,5 +63,4 @@ def test_policy_implementation(): '+ google_organization_iam_policy.authoritative,\n', '+ google_org_policy_custom_constraint.constraint,\n', '+ ]\n', - ' }\n', ] diff --git a/tests/modules/project/examples/iam-additive-members.yaml b/tests/modules/project/examples/iam-additive-members.yaml index 5832e4dcaa..6a517a4a1d 100644 --- a/tests/modules/project/examples/iam-additive-members.yaml +++ b/tests/modules/project/examples/iam-additive-members.yaml @@ -17,17 +17,14 @@ values: project_id: project-example module.project.google_project_iam_member.additive["roles/editor-user:two@example.org"]: condition: [] - member: user:two@example.org project: project-example role: roles/editor module.project.google_project_iam_member.additive["roles/owner-user:one@example.org"]: condition: [] - member: user:one@example.org project: project-example role: roles/owner module.project.google_project_iam_member.additive["roles/owner-user:two@example.org"]: condition: [] - member: user:two@example.org project: project-example role: roles/owner diff --git a/tests/modules/project/examples/iam-additive.yaml b/tests/modules/project/examples/iam-additive.yaml index f07b0df66e..5bab822321 100644 --- a/tests/modules/project/examples/iam-additive.yaml +++ b/tests/modules/project/examples/iam-additive.yaml @@ -16,22 +16,18 @@ values: module.project.google_project.project[0]: {} module.project.google_project_iam_member.additive["roles/owner-group:three@example.org"]: condition: [] - member: group:three@example.org project: project-example role: roles/owner module.project.google_project_iam_member.additive["roles/storage.objectAdmin-group:two@example.org"]: condition: [] - member: group:two@example.org project: project-example role: roles/storage.objectAdmin module.project.google_project_iam_member.additive["roles/viewer-group:one@example.org"]: condition: [] - member: group:one@example.org project: project-example role: roles/viewer module.project.google_project_iam_member.additive["roles/viewer-group:two@xample.org"]: condition: [] - member: group:two@xample.org project: project-example role: roles/viewer diff --git a/tests/modules/project/examples/org-policies.yaml b/tests/modules/project/examples/org-policies.yaml index 8841dedee8..d4dddc75bf 100644 --- a/tests/modules/project/examples/org-policies.yaml +++ b/tests/modules/project/examples/org-policies.yaml @@ -1,4 +1,4 @@ -# Copyright 2022 Google LLC +# 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. @@ -25,8 +25,8 @@ values: deny_all: null enforce: 'TRUE' values: [] - module.project.google_org_policy_policy.default["constraints/compute.skipDefaultNetworkCreation"]: - name: projects/foo-project-example/policies/constraints/compute.skipDefaultNetworkCreation + module.project.google_org_policy_policy.default["compute.skipDefaultNetworkCreation"]: + name: projects/foo-project-example/policies/compute.skipDefaultNetworkCreation parent: projects/foo-project-example spec: - inherit_from_parent: null @@ -37,8 +37,8 @@ values: deny_all: null enforce: 'TRUE' values: [] - module.project.google_org_policy_policy.default["constraints/compute.trustedImageProjects"]: - name: projects/foo-project-example/policies/constraints/compute.trustedImageProjects + module.project.google_org_policy_policy.default["compute.trustedImageProjects"]: + name: projects/foo-project-example/policies/compute.trustedImageProjects parent: projects/foo-project-example spec: - inherit_from_parent: null @@ -52,8 +52,8 @@ values: - allowed_values: - projects/my-project denied_values: null - module.project.google_org_policy_policy.default["constraints/compute.vmExternalIpAccess"]: - name: projects/foo-project-example/policies/constraints/compute.vmExternalIpAccess + module.project.google_org_policy_policy.default["compute.vmExternalIpAccess"]: + name: projects/foo-project-example/policies/compute.vmExternalIpAccess parent: projects/foo-project-example spec: - inherit_from_parent: null @@ -64,8 +64,8 @@ values: deny_all: 'TRUE' enforce: null values: [] - module.project.google_org_policy_policy.default["constraints/iam.allowedPolicyMemberDomains"]: - name: projects/foo-project-example/policies/constraints/iam.allowedPolicyMemberDomains + module.project.google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: + name: projects/foo-project-example/policies/iam.allowedPolicyMemberDomains parent: projects/foo-project-example spec: - inherit_from_parent: null @@ -102,7 +102,7 @@ values: - allow_all: null condition: - description: test condition - expression: resource.matchTagId("tagKeys/1234", "tagValues/1234") + expression: resource.matchTagId('tagKeys/1234', 'tagValues/1234') location: somewhere title: condition deny_all: null diff --git a/tests/modules/project/org_policies_boolean.tfvars b/tests/modules/project/org_policies_boolean.tfvars index eceafe6d29..cf5047a205 100644 --- a/tests/modules/project/org_policies_boolean.tfvars +++ b/tests/modules/project/org_policies_boolean.tfvars @@ -1,9 +1,8 @@ org_policies = { "iam.disableServiceAccountKeyCreation" = { - enforce = true + rules = [{ enforce = true }] } "iam.disableServiceAccountKeyUpload" = { - enforce = false rules = [ { condition = { @@ -13,6 +12,9 @@ org_policies = { location = "xxx" } enforce = true + }, + { + enforce = false } ] } diff --git a/tests/modules/project/org_policies_list.tfvars b/tests/modules/project/org_policies_list.tfvars index f9de8dbabe..4889547d2a 100644 --- a/tests/modules/project/org_policies_list.tfvars +++ b/tests/modules/project/org_policies_list.tfvars @@ -1,15 +1,16 @@ org_policies = { "compute.vmExternalIpAccess" = { - deny = { all = true } + rules = [{ deny = { all = true } }] } "iam.allowedPolicyMemberDomains" = { inherit_from_parent = true - allow = { - values = ["C0xxxxxxx", "C0yyyyyyy"] - } + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] } "compute.restrictLoadBalancerCreationForTypes" = { - deny = { values = ["in:EXTERNAL"] } rules = [ { condition = { @@ -32,6 +33,9 @@ org_policies = { allow = { all = true } + }, + { + deny = { values = ["in:EXTERNAL"] } } ] }