diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml
index 5de7336d..33693873 100644
--- a/.github/workflows/linting.yml
+++ b/.github/workflows/linting.yml
@@ -37,7 +37,7 @@ jobs:
- name: Set up Terraform
uses: hashicorp/setup-terraform@v1
with:
- terraform_version: 1.1.8
+ terraform_version: 1.3
- name: Install dependencies
run: |
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d8e4d144..a7e427d7 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -30,7 +30,7 @@ env:
PYTEST_ADDOPTS: "--color=yes"
PYTHON_VERSION: "3.10"
TF_PLUGIN_CACHE_DIR: "/home/runner/.terraform.d/plugin-cache"
- TF_VERSION: 1.1.8
+ TF_VERSION: 1.3.0
jobs:
doc-examples:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dcb1d931..5c602a02 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file.
### BLUEPRINTS
+- [[#839](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/839)] **incompatible change:** Update to terraform 1.3 ([juliocc](https://github.com/juliocc))
+- [[#828](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/828)] Update firewall rules. ([lcaggio](https://github.com/lcaggio))
- [[#813](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/813)] Add documentation example test for pf ([ludoo](https://github.com/ludoo))
- [[#809](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/809)] Renaming and moving blueprints ([juliocc](https://github.com/juliocc))
@@ -17,10 +19,27 @@ All notable changes to this project will be documented in this file.
### FAST
+- [[#842](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/842)] Comment redundant role in bootstrap stage, align IAM.md files, improve IAM tool ([ludoo](https://github.com/ludoo))
+- [[#841](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/841)] FAST: revert 00-cicd provider changes ([ludoo](https://github.com/ludoo))
+- [[#835](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/835)] Fix workflow-gitlab.yaml template rendering ([muresan](https://github.com/muresan))
+- [[#828](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/828)] Update firewall rules. ([lcaggio](https://github.com/lcaggio))
- [[#807](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/807)] FAST: refactor Gitlab template ([ludoo](https://github.com/ludoo))
+### MODULES
+
+- [[#843](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/843)] Add support for disk encryption to instance templates in compute-vm module ([ludoo](https://github.com/ludoo))
+- [[#840](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/840)] **incompatible change:** Refactor net-address module for 1.3 ([ludoo](https://github.com/ludoo))
+- [[#839](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/839)] **incompatible change:** Update to terraform 1.3 ([juliocc](https://github.com/juliocc))
+- [[#824](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/824)] Add simple composer 2 blueprint ([lcaggio](https://github.com/lcaggio))
+- [[#834](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/834)] Add support for service_label property in internal load balancer ([kmucha555](https://github.com/kmucha555))
+- [[#833](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/833)] regional MySQL DBs - automatic backup conf ([skalolazka](https://github.com/skalolazka))
+- [[#827](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/827)] Project module: Add Artifactregistry Service Identity SA creation. ([lcaggio](https://github.com/lcaggio))
+- [[#826](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/826)] Added new binary_authorization argument in gke-cluster module ([sirohia](https://github.com/sirohia))
+- [[#819](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/819)] Removed old and unused modules ([juliocc](https://github.com/juliocc))
+
### TOOLS
+- [[#842](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/842)] Comment redundant role in bootstrap stage, align IAM.md files, improve IAM tool ([ludoo](https://github.com/ludoo))
- [[#811](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/811)] Fix changelog generator ([ludoo](https://github.com/ludoo))
- [[#810](https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/pull/810)] Fully recursive e2e test runner for examples ([juliocc](https://github.com/juliocc))
diff --git a/blueprints/README.md b/blueprints/README.md
index b38370bb..61323dab 100644
--- a/blueprints/README.md
+++ b/blueprints/README.md
@@ -5,7 +5,7 @@ This section **[networking blueprints](./networking/)** that implement core patt
Currently available blueprints:
- **cloud operations** - [Resource tracking and remediation via Cloud Asset feeds](./cloud-operations/asset-inventory-feed-remediation), [Granular Cloud DNS IAM via Service Directory](./cloud-operations/dns-fine-grained-iam), [Granular Cloud DNS IAM for Shared VPC](./cloud-operations/dns-shared-vpc), [Compute Engine quota monitoring](./cloud-operations/quota-monitoring), [Scheduled Cloud Asset Inventory Export to Bigquery](./cloud-operations/scheduled-asset-inventory-export-bq), [Packer image builder](./cloud-operations/packer-image-builder), [On-prem SA key management](./cloud-operations/onprem-sa-key-management), [TCP healthcheck for unmanaged GCE instances](./cloud-operations/unmanaged-instances-healthcheck), [HTTP Load Balancer with Cloud Armor](./cloud-operations/glb_and_armor)
-- **data solutions** - [GCE/GCS CMEK via centralized Cloud KMS](./data-solutions/gcs-to-bq-with-least-privileges/), [Cloud Storage to Bigquery with Cloud Dataflow with least privileges](./data-solutions/gcs-to-bq-with-least-privileges/), [Data Platform Foundations](./data-solutions/data-platform-foundations/), [SQL Server AlwaysOn availability groups blueprint](./data-solutions/sqlserver-alwayson), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion/)
+- **data solutions** - [GCE/GCS CMEK via centralized Cloud KMS](./data-solutions/gcs-to-bq-with-least-privileges/), [Cloud Storage to Bigquery with Cloud Dataflow with least privileges](./data-solutions/gcs-to-bq-with-least-privileges/), [Data Platform Foundations](./data-solutions/data-platform-foundations/), [SQL Server AlwaysOn availability groups blueprint](./data-solutions/sqlserver-alwayson), [Cloud SQL instance with multi-region read replicas](./data-solutions/cloudsql-multiregion/), [Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key](./data-solutions/composer-2/)
- **factories** - [The why and the how of resource factories](./factories/README.md)
- **GKE** - [GKE multitenant fleet](./gke/multitenant-fleet/), [Shared VPC with GKE support](./networking/shared-vpc-gke/), [Binary Authorization Pipeline](./gke/binauthz/), [Multi-cluster mesh on GKE (fleet API)](./gke/multi-cluster-mesh-gke-fleet-api/)
- **networking** - [hub and spoke via peering](./networking/hub-and-spoke-peering/), [hub and spoke via VPN](./networking/hub-and-spoke-vpn/), [DNS and Google Private Access for on-premises](./networking/onprem-google-access-dns/), [Shared VPC with GKE support](./networking/shared-vpc-gke/), [ILB as next hop](./networking/ilb-next-hop), [PSC for on-premises Cloud Function invocation](./networking/private-cloud-function-from-onprem/), [decentralized firewall](./networking/decentralized-firewall)
diff --git a/blueprints/cloud-operations/adfs/versions.tf b/blueprints/cloud-operations/adfs/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/adfs/versions.tf
+++ b/blueprints/cloud-operations/adfs/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf b/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf
+++ b/blueprints/cloud-operations/asset-inventory-feed-remediation/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf b/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf
+++ b/blueprints/cloud-operations/dns-fine-grained-iam/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/dns-shared-vpc/versions.tf b/blueprints/cloud-operations/dns-shared-vpc/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/dns-shared-vpc/versions.tf
+++ b/blueprints/cloud-operations/dns-shared-vpc/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf b/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf
+++ b/blueprints/cloud-operations/iam-delegated-role-grants/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/onprem-sa-key-management/versions.tf b/blueprints/cloud-operations/onprem-sa-key-management/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/onprem-sa-key-management/versions.tf
+++ b/blueprints/cloud-operations/onprem-sa-key-management/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/packer-image-builder/versions.tf b/blueprints/cloud-operations/packer-image-builder/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/packer-image-builder/versions.tf
+++ b/blueprints/cloud-operations/packer-image-builder/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/cloud-operations/quota-monitoring/versions.tf b/blueprints/cloud-operations/quota-monitoring/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/quota-monitoring/versions.tf
+++ b/blueprints/cloud-operations/quota-monitoring/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
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 4278054b..8abac788 100644
--- a/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/versions.tf
+++ b/blueprints/cloud-operations/scheduled-asset-inventory-export-bq/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/data-solutions/README.md b/blueprints/data-solutions/README.md
index 4abebf9d..819861eb 100644
--- a/blueprints/data-solutions/README.md
+++ b/blueprints/data-solutions/README.md
@@ -30,7 +30,7 @@ This [blueprint](./data-platform-foundations/) implements SQL Server Always On A
### Cloud SQL instance with multi-region read replicas
-
+
This [blueprint](./cloudsql-multiregion/) creates a [Cloud SQL instance](https://cloud.google.com/sql) with multi-region read replicas as described in the [Cloud SQL for PostgreSQL disaster recovery](https://cloud.google.com/architecture/cloud-sql-postgres-disaster-recovery-complete-failover-fallback) article.
@@ -41,3 +41,10 @@ This [blueprint](./data-playground/) creates a [Vertex AI
Notebook](https://cloud.google.com/vertex-ai/docs/workbench/introduction)
running on a VPC with a private IP and a dedicated Service Account. A GCS bucket and a BigQuery dataset are created to store inputs and outputs of data experiments.
+
+### Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key
+
+
+This [blueprint](./composer-2/) creates a [Cloud Composer](https://cloud.google.com/composer/) version 2 instance on a VPC with a dedicated service account. The solution supports as inputs: a Shared VPC and Cloud KMS CMEK keys.
+
\ No newline at end of file
diff --git a/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf b/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf
+++ b/blueprints/data-solutions/cmek-via-centralized-kms/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/data-solutions/composer-2/README.md b/blueprints/data-solutions/composer-2/README.md
new file mode 100644
index 00000000..4ee62126
--- /dev/null
+++ b/blueprints/data-solutions/composer-2/README.md
@@ -0,0 +1,115 @@
+# Cloud Composer version 2 private instance, supporting Shared VPC and external CMEK key
+
+This blueprint creates a Private instance of [Cloud Composer version 2](https://cloud.google.com/composer/docs/composer-2/composer-versioning-overview) on a VPC with a dedicated service account. Cloud Composer 2 is the new major version for Cloud Composer that supports:
+ - environment autoscaling
+ - workloads configuration: CPU, memory, and storage parameters for Airflow workers, schedulers, web server, and database.
+
+Please consult the [documentation page](https://cloud.google.com/composer/docs/composer-2/composer-versioning-overview) for an exhaustive comparison between Composer Version 1 and Version 2.
+
+The solution will use:
+ - Cloud Composer
+ - VPC with Private Service Access to deploy resources, if no Shared VPC configuration provided.
+ - Google Cloud NAT to access internet resources, if no Shared VPC configuration provided.
+
+The solution supports as inputs:
+ - Shared VPC
+ - Cloud KMS CMEK keys
+
+This is the high level diagram:
+
+![Cloud Composer 2 architecture overview](./diagram.png "Cloud Composer 2 architecture overview")
+
+# Requirements
+This blueprint will deploy all its resources into the project defined by the project_id variable. Please note that we assume this project already exists. However, if you provide the appropriate values to the `project_create` variable, the project will be created as part of the deployment.
+
+If `project_create` is left to null, the identity performing the deployment needs the owner role on the project defined by the `project_id` variable. Otherwise, the identity performing the deployment needs `resourcemanager.projectCreator` on the resource hierarchy node specified by `project_create.parent` and `billing.user` on the billing account specified by `project_create.billing_account_id`.
+
+# Deployment
+Run Terraform init:
+
+```bash
+$ terraform init
+```
+
+Configure the Terraform variable in your terraform.tfvars file. You need to specify at least the following variables:
+
+```tfvars
+project_id = "lcaggioni-sandbox"
+prefix = "lc"
+```
+
+You can run now:
+
+```bash
+$ terraform apply
+```
+
+You can now connect to your instance.
+
+# Customizations
+
+## VPC
+If a shared VPC is not configured, a VPC will be created within the project. The following IP ranges will be used:
+- Cloudsql: `10.20.10.0/24`
+- GKE: `10.20.11.0/28`
+
+Change the code as needed to match your needed configuration, remember that these addresses should not overlap with any other range used in network.
+## Shared VPC
+As is often the case in real-world configurations, this blueprint accepts as input an existing [`Shared-VPC`](https://cloud.google.com/vpc/docs/shared-vpc) via the `network_config` variable.
+
+Example:
+```tfvars
+network_config = {
+ host_project = "PROJECT"
+ network_self_link = "projects/PROJECT/global/networks/VPC_NAME"
+ subnet_self_link = "projects/PROJECT/regions/REGION/subnetworks/VPC_NAME"
+ composer_secondary_ranges = {
+ pods = "pods"
+ services = "services"
+ }
+}
+```
+
+Make sure that:
+- The GKE API (`container.googleapis.com`) is enabled in the VPC host project.
+- The subnet has secondary ranges configured with 2 ranges:
+ - pods: `/22` example: `10.10.8.0/22`
+ - services = `/24` example: 10.10.12.0/24`
+- Firewall rules are set, as described in the [documentation](https://cloud.google.com/composer/docs/composer-2/configure-private-ip#step_3_configure_firewall_rules)
+
+In order to run the example and deploy Cloud Composer on a shared VPC the identity running Terraform must have the following IAM role on the Shared VPC Host project.
+ - Compute Network Admin (roles/compute.networkAdmin)
+ - Compute Shared VPC Admin (roles/compute.xpnAdmin)
+
+## Encryption
+As is often the case in real-world configurations, this blueprint accepts as input an existing [`Cloud KMS keys`](https://cloud.google.com/kms/docs/cmek) via the `service_encryption_keys` variable.
+
+Example:
+```tfvars
+service_encryption_keys = {
+ `europe/west1` = `projects/PROJECT/locations/REGION/keyRings/KR_NAME/cryptoKeys/KEY_NAME`
+}
+```
+
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---:|:---:|:---:|
+| [prefix](variables.tf#L81) | Unique prefix used for resource names. Not used for project if 'project_create' is null. | string
| ✓ | |
+| [project_id](variables.tf#L95) | Project id, references existing project if `project_create` is null. | string
| ✓ | |
+| [composer_config](variables.tf#L17) | Composer environemnt configuration. See [attribute reference](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/composer_environment#argument-reference---cloud-composer-2) for details on settings variables. | object({…})
| | {…}
|
+| [iam_groups_map](variables.tf#L61) | Map of Role => groups to be added on the project. Example: { \"roles/composer.admin\" = [\"group:gcp-data-engineers@example.com\"]}. | map(list(string))
| | null
|
+| [network_config](variables.tf#L67) | Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values. | object({…})
| | null
|
+| [project_create](variables.tf#L86) | Provide values if project creation is needed, uses existing project if null. Parent is in 'folders/nnn' or 'organizations/nnn' format. | object({…})
| | null
|
+| [region](variables.tf#L100) | Region where instances will be deployed. | string
| | "europe-west1"
|
+| [service_encryption_keys](variables.tf#L106) | Cloud KMS keys to use to encrypt resources. Provide a key for each reagion in use. | map(string)
| | null
|
+
+## Outputs
+
+| name | description | sensitive |
+|---|---|:---:|
+| [composer_airflow_uri](outputs.tf#L22) | The URI of the Apache Airflow Web UI hosted within the Cloud Composer environment.. | |
+| [composer_dag_gcs](outputs.tf#L17) | The Cloud Storage prefix of the DAGs for the Cloud Composer environment. | |
+
+
diff --git a/blueprints/data-solutions/composer-2/backend.tf.sample b/blueprints/data-solutions/composer-2/backend.tf.sample
new file mode 100644
index 00000000..49a0883d
--- /dev/null
+++ b/blueprints/data-solutions/composer-2/backend.tf.sample
@@ -0,0 +1,30 @@
+# 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.
+
+# The `impersonate_service_account` option require the identity launching terraform
+# role `roles/iam.serviceAccountTokenCreator` on the Service Account specified.
+
+terraform {
+ backend "gcs" {
+ bucket = "BUCKET_NAME"
+ prefix = "PREFIX"
+ impersonate_service_account = "SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com"
+ }
+}
+provider "google" {
+ impersonate_service_account = "SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com"
+}
+provider "google-beta" {
+ impersonate_service_account = "SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com"
+}
\ No newline at end of file
diff --git a/blueprints/data-solutions/composer-2/composer.tf b/blueprints/data-solutions/composer-2/composer.tf
new file mode 100644
index 00000000..1217e0d4
--- /dev/null
+++ b/blueprints/data-solutions/composer-2/composer.tf
@@ -0,0 +1,111 @@
+/**
+ * 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 "comp-sa" {
+ source = "../../../modules/iam-service-account"
+ project_id = module.project.project_id
+ prefix = var.prefix
+ name = "cmp"
+ display_name = "Composer service account"
+}
+
+resource "google_composer_environment" "env" {
+ name = "${var.prefix}-composer"
+ project = module.project.project_id
+ region = var.region
+ config {
+ dynamic "software_config" {
+ for_each = (
+ try(var.composer_config.software_config, null) != null
+ ? { 1 = 1 }
+ : {}
+ )
+ content {
+ airflow_config_overrides = try(var.composer_config.software_config.airflow_config_overrides, null)
+ pypi_packages = try(var.composer_config.software_config.pypi_packages, null)
+ env_variables = try(var.composer_config.software_config.env_variables, null)
+ image_version = try(var.composer_config.software_config.image_version, null)
+ python_version = try(var.composer_config.software_config.python_version, null)
+ scheduler_count = try(var.composer_config.software_config.scheduler_count, null)
+ }
+ }
+ dynamic "workloads_config" {
+ for_each = (try(var.composer_config.workloads_config, null) != null ? { 1 = 1 } : {})
+
+ content {
+ scheduler {
+ cpu = try(var.composer_config.workloads_config.scheduler.cpu, null)
+ memory_gb = try(var.composer_config.workloads_config.scheduler.memory_gb, null)
+ storage_gb = try(var.composer_config.workloads_config.scheduler.storage_gb, null)
+ count = try(var.composer_config.workloads_config.scheduler.count, null)
+ }
+ web_server {
+ cpu = try(var.composer_config.workloads_config.web_server.cpu, null)
+ memory_gb = try(var.composer_config.workloads_config.web_server.memory_gb, null)
+ storage_gb = try(var.composer_config.workloads_config.web_server.storage_gb, null)
+ }
+ worker {
+ cpu = try(var.composer_config.workloads_config.worker.cpu, null)
+ memory_gb = try(var.composer_config.workloads_config.worker.memory_gb, null)
+ storage_gb = try(var.composer_config.workloads_config.worker.storage_gb, null)
+ min_count = try(var.composer_config.workloads_config.worker.min_count, null)
+ max_count = try(var.composer_config.workloads_config.worker.max_count, null)
+ }
+ }
+ }
+
+ environment_size = var.composer_config.environment_size
+
+ node_config {
+ network = local.orch_vpc
+ subnetwork = local.orch_subnet
+ service_account = module.comp-sa.email
+ enable_ip_masq_agent = "true"
+ tags = ["composer-worker"]
+ ip_allocation_policy {
+ cluster_secondary_range_name = try(
+ var.network_config.composer_secondary_ranges.pods, "pods"
+ )
+ services_secondary_range_name = try(
+ var.network_config.composer_secondary_ranges.services, "services"
+ )
+ }
+ }
+ private_environment_config {
+ enable_private_endpoint = "true"
+ cloud_sql_ipv4_cidr_block = try(
+ var.network_config.composer_ip_ranges.cloudsql, "10.20.10.0/24"
+ )
+ master_ipv4_cidr_block = try(
+ var.network_config.composer_ip_ranges.gke_master, "10.20.11.0/28"
+ )
+ }
+ dynamic "encryption_config" {
+ for_each = (
+ try(var.service_encryption_keys[var.region], null) != null
+ ? { 1 = 1 }
+ : {}
+ )
+ content {
+ kms_key_name = try(var.service_encryption_keys[var.region], null)
+ }
+ }
+ }
+ depends_on = [
+ google_project_iam_member.shared_vpc,
+ module.project
+ ]
+}
diff --git a/blueprints/data-solutions/composer-2/diagram.png b/blueprints/data-solutions/composer-2/diagram.png
new file mode 100644
index 00000000..b8ffc12e
Binary files /dev/null and b/blueprints/data-solutions/composer-2/diagram.png differ
diff --git a/blueprints/data-solutions/composer-2/main.tf b/blueprints/data-solutions/composer-2/main.tf
new file mode 100644
index 00000000..c55113e0
--- /dev/null
+++ b/blueprints/data-solutions/composer-2/main.tf
@@ -0,0 +1,148 @@
+/**
+ * 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 {
+ iam = merge(
+ {
+ "roles/composer.worker" = [module.comp-sa.iam_email]
+ "roles/composer.ServiceAgentV2Ext" = ["serviceAccount:${module.project.service_accounts.robots.composer}"]
+ },
+ var.iam_groups_map
+ )
+
+ # Adding Roles on Service Identities Service account as per documentation: https://cloud.google.com/composer/docs/composer-2/configure-shared-vpc#edit_permissions_for_the_google_apis_service_account
+ _shared_vpc_bindings = {
+ "roles/compute.networkUser" = [
+ "prj-cloudservices", "prj-robot-gke"
+ ]
+ "roles/composer.sharedVpcAgent" = [
+ "prj-robot-cs"
+ ]
+ "roles/container.hostServiceAgentUser" = [
+ "prj-robot-gke"
+ ]
+ }
+ shared_vpc_role_members = {
+ prj-cloudservices = "serviceAccount:${module.project.service_accounts.cloud_services}"
+ prj-robot-gke = "serviceAccount:${module.project.service_accounts.robots.container-engine}"
+ prj-robot-cs = "serviceAccount:${module.project.service_accounts.robots.composer}"
+ }
+ # reassemble in a format suitable for for_each
+ shared_vpc_bindings_map = {
+ for binding in flatten([
+ for role, members in local._shared_vpc_bindings : [
+ for member in members : { role = role, member = member }
+ ]
+ ]) : "${binding.role}-${binding.member}" => binding
+ }
+
+ shared_vpc_project = try(var.network_config.host_project, null)
+ use_shared_vpc = var.network_config != null
+
+ vpc_self_link = (
+ local.use_shared_vpc
+ ? var.network_config.network_self_link
+ : module.vpc.0.self_link
+ )
+
+ orch_subnet = (
+ local.use_shared_vpc
+ ? var.network_config.subnet_self_link
+ : values(module.vpc.0.subnet_self_links)[0]
+ )
+
+ orch_vpc = (
+ local.use_shared_vpc
+ ? var.network_config.network_self_link
+ : module.vpc.0.self_link
+ )
+}
+
+module "project" {
+ source = "../../../modules/project"
+ name = var.project_id
+ parent = try(var.project_create.parent, null)
+ billing_account = try(var.project_create.billing_account_id, null)
+ project_create = var.project_create != null
+ prefix = var.project_create == null ? null : var.prefix
+ iam = var.project_create != null ? local.iam : {}
+ iam_additive = var.project_create == null ? local.iam : {}
+ services = [
+ "artifactregistry.googleapis.com",
+ "cloudkms.googleapis.com",
+ "container.googleapis.com",
+ "containerregistry.googleapis.com",
+ "composer.googleapis.com",
+ "compute.googleapis.com",
+ "iap.googleapis.com",
+ "logging.googleapis.com",
+ "monitoring.googleapis.com",
+ "networkmanagement.googleapis.com",
+ "servicenetworking.googleapis.com",
+ "storage.googleapis.com",
+ "storage-component.googleapis.com",
+ ]
+
+ shared_vpc_service_config = local.shared_vpc_project == null ? null : {
+ attach = true
+ host_project = local.shared_vpc_project
+ service_identity_iam = {}
+ }
+
+ service_encryption_key_ids = {
+ composer = [try(lookup(var.service_encryption_keys, var.region, null), null)]
+ }
+
+ service_config = {
+ disable_on_destroy = false, disable_dependent_services = false
+ }
+}
+
+module "vpc" {
+ source = "../../../modules/net-vpc"
+ count = local.use_shared_vpc ? 0 : 1
+ project_id = module.project.project_id
+ name = "vpc"
+ subnets = [
+ {
+ ip_cidr_range = "10.0.0.0/20"
+ name = "subnet"
+ region = var.region
+ secondary_ip_range = {
+ pods = "10.10.8.0/22"
+ services = "10.10.12.0/24"
+ }
+ }
+ ]
+}
+
+# No explicit firewall rules set, created automatically by GKE autopilot
+
+module "nat" {
+ source = "../../../modules/net-cloudnat"
+ count = local.use_shared_vpc ? 0 : 1
+ project_id = module.project.project_id
+ region = var.region
+ name = "${var.prefix}-default"
+ router_network = module.vpc.0.name
+}
+
+resource "google_project_iam_member" "shared_vpc" {
+ for_each = local.use_shared_vpc ? local.shared_vpc_bindings_map : {}
+ project = var.network_config.host_project
+ role = each.value.role
+ member = lookup(local.shared_vpc_role_members, each.value.member)
+}
diff --git a/blueprints/data-solutions/composer-2/outputs.tf b/blueprints/data-solutions/composer-2/outputs.tf
new file mode 100644
index 00000000..a2943006
--- /dev/null
+++ b/blueprints/data-solutions/composer-2/outputs.tf
@@ -0,0 +1,25 @@
+/**
+ * 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.
+ */
+
+output "composer_dag_gcs" {
+ description = "The Cloud Storage prefix of the DAGs for the Cloud Composer environment."
+ value = google_composer_environment.env.config[0].dag_gcs_prefix
+}
+
+output "composer_airflow_uri" {
+ description = "The URI of the Apache Airflow Web UI hosted within the Cloud Composer environment.."
+ value = google_composer_environment.env.config[0].airflow_uri
+}
diff --git a/blueprints/data-solutions/composer-2/variables.tf b/blueprints/data-solutions/composer-2/variables.tf
new file mode 100644
index 00000000..db7ac55a
--- /dev/null
+++ b/blueprints/data-solutions/composer-2/variables.tf
@@ -0,0 +1,107 @@
+/**
+ * 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 "composer_config" {
+ description = "Composer environment configuration. It accepts only following attributes: `environment_size`, `software_config` and `workloads_config`. See [attribute reference](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/composer_environment#argument-reference---cloud-composer-2) for details on settings variables."
+ type = object({
+ environment_size = string
+ software_config = any
+ workloads_config = object({
+ scheduler = object(
+ {
+ cpu = number
+ memory_gb = number
+ storage_gb = number
+ count = number
+ }
+ )
+ web_server = object(
+ {
+ cpu = number
+ memory_gb = number
+ storage_gb = number
+ }
+ )
+ worker = object(
+ {
+ cpu = number
+ memory_gb = number
+ storage_gb = number
+ min_count = number
+ max_count = number
+ }
+ )
+ })
+ })
+ default = {
+ environment_size = "ENVIRONMENT_SIZE_SMALL"
+ software_config = {
+ image_version = "composer-2-airflow-2"
+ }
+ workloads_config = null
+ }
+}
+
+variable "iam_groups_map" {
+ description = "Map of Role => groups to be added on the project. Example: { \"roles/composer.admin\" = [\"group:gcp-data-engineers@example.com\"]}."
+ type = map(list(string))
+ default = null
+}
+
+variable "network_config" {
+ description = "Shared VPC network configurations to use. If null networks will be created in projects with preconfigured values."
+ type = object({
+ host_project = string
+ network_self_link = string
+ subnet_self_link = string
+ composer_secondary_ranges = object({
+ pods = string
+ services = string
+ })
+ })
+ default = null
+}
+
+variable "prefix" {
+ description = "Unique prefix used for resource names. Not used for project if 'project_create' is null."
+ type = string
+}
+
+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 = null
+}
+
+variable "project_id" {
+ description = "Project id, references existing project if `project_create` is null."
+ type = string
+}
+
+variable "region" {
+ description = "Reagion where instances will be deployed."
+ type = string
+ default = "europe-west1"
+}
+
+variable "service_encryption_keys" {
+ description = "Cloud KMS keys to use to encrypt resources. Provide a key for each reagion in use."
+ type = map(string)
+ default = null
+}
diff --git a/blueprints/data-solutions/data-platform-foundations/README.md b/blueprints/data-solutions/data-platform-foundations/README.md
index 76810f54..d2b88550 100644
--- a/blueprints/data-solutions/data-platform-foundations/README.md
+++ b/blueprints/data-solutions/data-platform-foundations/README.md
@@ -222,7 +222,7 @@ module "data-platform" {
prefix = "myprefix"
}
-# tftest modules=42 resources=314
+# tftest modules=42 resources=315
```
## Customizations
diff --git a/blueprints/data-solutions/data-platform-foundations/variables.tf b/blueprints/data-solutions/data-platform-foundations/variables.tf
index ac8d06b4..dc59de29 100644
--- a/blueprints/data-solutions/data-platform-foundations/variables.tf
+++ b/blueprints/data-solutions/data-platform-foundations/variables.tf
@@ -28,7 +28,7 @@ variable "composer_config" {
})
default = {
node_count = 3
- airflow_version = "composer-1.17.5-airflow-2.1.4"
+ airflow_version = "composer-1-airflow-2"
env_variables = {}
}
}
diff --git a/blueprints/data-solutions/data-playground/versions.tf b/blueprints/data-solutions/data-playground/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/data-solutions/data-playground/versions.tf
+++ b/blueprints/data-solutions/data-playground/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
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 4278054b..8abac788 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
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/factories/net-vpc-firewall-yaml/versions.tf b/blueprints/factories/net-vpc-firewall-yaml/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/factories/net-vpc-firewall-yaml/versions.tf
+++ b/blueprints/factories/net-vpc-firewall-yaml/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/decentralized-firewall/versions.tf b/blueprints/networking/decentralized-firewall/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/decentralized-firewall/versions.tf
+++ b/blueprints/networking/decentralized-firewall/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/filtering-proxy/versions.tf b/blueprints/networking/filtering-proxy/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/filtering-proxy/versions.tf
+++ b/blueprints/networking/filtering-proxy/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/hub-and-spoke-peering/versions.tf b/blueprints/networking/hub-and-spoke-peering/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/hub-and-spoke-peering/versions.tf
+++ b/blueprints/networking/hub-and-spoke-peering/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/hub-and-spoke-vpn/versions.tf b/blueprints/networking/hub-and-spoke-vpn/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/hub-and-spoke-vpn/versions.tf
+++ b/blueprints/networking/hub-and-spoke-vpn/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/ilb-next-hop/versions.tf b/blueprints/networking/ilb-next-hop/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/ilb-next-hop/versions.tf
+++ b/blueprints/networking/ilb-next-hop/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/onprem-google-access-dns/versions.tf b/blueprints/networking/onprem-google-access-dns/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/onprem-google-access-dns/versions.tf
+++ b/blueprints/networking/onprem-google-access-dns/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/private-cloud-function-from-onprem/versions.tf b/blueprints/networking/private-cloud-function-from-onprem/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/private-cloud-function-from-onprem/versions.tf
+++ b/blueprints/networking/private-cloud-function-from-onprem/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/networking/shared-vpc-gke/versions.tf b/blueprints/networking/shared-vpc-gke/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/networking/shared-vpc-gke/versions.tf
+++ b/blueprints/networking/shared-vpc-gke/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/blueprints/third-party-solutions/openshift/tf/versions.tf b/blueprints/third-party-solutions/openshift/tf/versions.tf
index 4278054b..8abac788 100644
--- a/blueprints/third-party-solutions/openshift/tf/versions.tf
+++ b/blueprints/third-party-solutions/openshift/tf/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/default-versions.tf b/default-versions.tf
index 4278054b..8abac788 100644
--- a/default-versions.tf
+++ b/default-versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/fast/assets/templates/workflow-gitlab.yaml b/fast/assets/templates/workflow-gitlab.yaml
index b685be8a..8981e70b 100644
--- a/fast/assets/templates/workflow-gitlab.yaml
+++ b/fast/assets/templates/workflow-gitlab.yaml
@@ -14,7 +14,7 @@
default:
before_script:
- - echo "${CI_JOB_JWT_V2}" > token.txt
+ - echo "$${CI_JOB_JWT_V2}" > token.txt
image:
name: hashicorp/terraform
entrypoint:
@@ -49,10 +49,10 @@ gcp-auth:
script:
- |
gcloud iam workload-identity-pools create-cred-config \
- ${FAST_WIF_PROVIDER} \
- --service-account=${FAST_SERVICE_ACCOUNT} \
+ $${FAST_WIF_PROVIDER} \
+ --service-account=$${FAST_SERVICE_ACCOUNT} \
--service-account-token-lifetime-seconds=3600 \
- --output-file=${GOOGLE_CREDENTIALS} \
+ --output-file=$${GOOGLE_CREDENTIALS} \
--credential-source-file=token.txt
tf-files:
dependencies:
@@ -62,14 +62,14 @@ tf-files:
stage: tf-files
script:
# - gcloud components install -q alpha
- - gcloud config set auth/credential_file_override ${GOOGLE_CREDENTIALS}
+ - gcloud config set auth/credential_file_override $${GOOGLE_CREDENTIALS}
- mkdir -p .tf-setup
- |
gcloud alpha storage cp -r \
- "gs://${FAST_OUTPUTS_BUCKET}/providers/${TF_PROVIDERS_FILE}" .tf-setup/
+ "gs://$${FAST_OUTPUTS_BUCKET}/providers/$${TF_PROVIDERS_FILE}" .tf-setup/
- |
gcloud alpha storage cp -r \
- "gs://${FAST_OUTPUTS_BUCKET}/tfvars" .tf-setup/
+ "gs://$${FAST_OUTPUTS_BUCKET}/tfvars" .tf-setup/
tf-plan:
# uncomment the following lines and set the SSH key secret for private modules repo
@@ -82,9 +82,9 @@ tf-plan:
# ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts
stage: tf-plan
script:
- - cp .tf-setup/${TF_PROVIDERS_FILE} ./
+ - cp .tf-setup/$${TF_PROVIDERS_FILE} ./
- |
- for f in ${TF_VAR_FILES}; do
+ for f in $${TF_VAR_FILES}; do
ln -s ".tf-setup/tfvars/$f" ./
done
- terraform init
@@ -104,9 +104,9 @@ tf-apply:
# ssh-keyscan gitlab.com | sort -u - ~/.ssh/known_hosts -o ~/.ssh/known_hosts
stage: tf-apply
script:
- - cp .tf-setup/${TF_PROVIDERS_FILE} ./
+ - cp .tf-setup/$${TF_PROVIDERS_FILE} ./
- |
- for f in ${TF_VAR_FILES}; do
+ for f in $${TF_VAR_FILES}; do
ln -s ".tf-setup/tfvars/$f" ./
done
- terraform init
diff --git a/fast/stages/00-bootstrap/IAM.md b/fast/stages/00-bootstrap/IAM.md
index 8ed7a126..7e7d7c19 100644
--- a/fast/stages/00-bootstrap/IAM.md
+++ b/fast/stages/00-bootstrap/IAM.md
@@ -6,13 +6,13 @@ Legend: +
additive, •
conditional.
| members | roles |
|---|---|
-|GCP organization domain
domain|[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser)
[roles/resourcemanager.organizationViewer](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationViewer) |
+|GCP organization domain
domain|[roles/browser](https://cloud.google.com/iam/docs/understanding-roles#browser) |
|gcp-billing-admins
group|[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
|
|gcp-network-admins
group|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner)
[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/compute.orgFirewallPolicyAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.orgFirewallPolicyAdmin) +
[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) +
|
|gcp-organization-admins
group|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner)
[roles/cloudsupport.admin](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.admin)
[roles/compute.osAdminLogin](https://cloud.google.com/iam/docs/understanding-roles#compute.osAdminLogin)
[roles/compute.osLoginExternalUser](https://cloud.google.com/iam/docs/understanding-roles#compute.osLoginExternalUser)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
|
|gcp-security-admins
group|[roles/cloudasset.owner](https://cloud.google.com/iam/docs/understanding-roles#cloudasset.owner)
[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/iam.securityReviewer](https://cloud.google.com/iam/docs/understanding-roles#iam.securityReviewer)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/securitycenter.admin](https://cloud.google.com/iam/docs/understanding-roles#securitycenter.admin)
[roles/accesscontextmanager.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#accesscontextmanager.policyAdmin) +
[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) +
[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
|
|gcp-support
group|[roles/cloudsupport.techSupportEditor](https://cloud.google.com/iam/docs/understanding-roles#cloudsupport.techSupportEditor)
[roles/logging.viewer](https://cloud.google.com/iam/docs/understanding-roles#logging.viewer)
[roles/monitoring.viewer](https://cloud.google.com/iam/docs/understanding-roles#monitoring.viewer) |
-|prod-bootstrap-0
serviceAccount|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) +
|
+|prod-bootstrap-0
serviceAccount|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/resourcemanager.organizationAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.organizationAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/resourcemanager.projectMover](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectMover)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/iam.organizationRoleAdmin](https://cloud.google.com/iam/docs/understanding-roles#iam.organizationRoleAdmin) +
|
|prod-resman-0
serviceAccount|organizations/[org_id #0]/roles/organizationIamAdmin •
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.tagAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagAdmin)
[roles/resourcemanager.tagUser](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.tagUser)
[roles/billing.admin](https://cloud.google.com/iam/docs/understanding-roles#billing.admin) +
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
|
## Project prod-audit-logs-0
diff --git a/fast/stages/00-bootstrap/organization.tf b/fast/stages/00-bootstrap/organization.tf
index 2aa21f8d..39845012 100644
--- a/fast/stages/00-bootstrap/organization.tf
+++ b/fast/stages/00-bootstrap/organization.tf
@@ -34,9 +34,10 @@ locals {
[module.automation-tf-bootstrap-sa.iam_email],
local._iam_bootstrap_user
)
- "roles/resourcemanager.organizationViewer" = [
- "domain:${var.organization.domain}"
- ]
+ # the following is useful if roles/browser is not desirable
+ # "roles/resourcemanager.organizationViewer" = [
+ # "domain:${var.organization.domain}"
+ # ]
"roles/resourcemanager.projectCreator" = concat(
[module.automation-tf-bootstrap-sa.iam_email],
local._iam_bootstrap_user
diff --git a/fast/stages/00-cicd/versions.tf b/fast/stages/00-cicd/versions.tf
index 4278054b..3a6a1ed8 100644
--- a/fast/stages/00-cicd/versions.tf
+++ b/fast/stages/00-cicd/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
@@ -24,6 +24,14 @@ terraform {
version = ">= 4.32.0" # tftest
}
}
+ github = {
+ source = "integrations/github"
+ version = "~> 4.0"
+ }
+ gitlab = {
+ source = "gitlabhq/gitlab"
+ version = ">= 3.16.1"
+ }
}
diff --git a/fast/stages/01-resman/IAM.md b/fast/stages/01-resman/IAM.md
index cbd989d9..78fac484 100644
--- a/fast/stages/01-resman/IAM.md
+++ b/fast/stages/01-resman/IAM.md
@@ -7,18 +7,45 @@ Legend: +
additive, •
conditional.
| members | roles |
|---|---|
|dev-resman-dp-0
serviceAccount|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
•
[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
+|dev-resman-gke-0
serviceAccount|[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
|dev-resman-pf-0
serviceAccount|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
•
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
|prod-resman-dp-0
serviceAccount|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
•
[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
+|prod-resman-gke-0
serviceAccount|[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
|prod-resman-net-0
serviceAccount|[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
[roles/compute.orgFirewallPolicyAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.orgFirewallPolicyAdmin) +
[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) +
|
|prod-resman-pf-0
serviceAccount|[roles/orgpolicy.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#orgpolicy.policyAdmin) +
•
[roles/billing.costsManager](https://cloud.google.com/iam/docs/understanding-roles#billing.costsManager) +
[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
|prod-resman-sec-0
serviceAccount|[roles/accesscontextmanager.policyAdmin](https://cloud.google.com/iam/docs/understanding-roles#accesscontextmanager.policyAdmin) +
[roles/billing.user](https://cloud.google.com/iam/docs/understanding-roles#billing.user) +
|
-## Folder development
+## Folder development [#0]
| members | roles |
|---|---|
-|dev-resman-dp-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) |
-|dev-resman-pf-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) |
+|dev-resman-dp-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder development [#1]
+
+| members | roles |
+|---|---|
+|dev-resman-gke-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder development [#2]
+
+| members | roles |
+|---|---|
+|dev-resman-dp-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin |
+|dev-resman-gke-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin |
+|dev-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin |
+
+## Folder development [#3]
+
+| members | roles |
+|---|---|
+|dev-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder development [#4]
+
+| members | roles |
+|---|---|
+|dev-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
## Folder networking
@@ -27,12 +54,37 @@ Legend: +
additive, •
conditional.
|gcp-network-admins
group|[roles/editor](https://cloud.google.com/iam/docs/understanding-roles#editor) |
|prod-resman-net-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
-## Folder production
+## Folder production [#0]
| members | roles |
|---|---|
-|prod-resman-dp-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator)
[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) |
-|prod-resman-pf-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin) |
+|prod-resman-dp-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder production [#1]
+
+| members | roles |
+|---|---|
+|prod-resman-gke-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder production [#2]
+
+| members | roles |
+|---|---|
+|prod-resman-dp-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin |
+|prod-resman-gke-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin |
+|prod-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin |
+
+## Folder production [#3]
+
+| members | roles |
+|---|---|
+|prod-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder production [#4]
+
+| members | roles |
+|---|---|
+|prod-resman-pf-0
serviceAccount|organizations/[org_id #0]/roles/serviceProjectNetworkAdmin
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
## Folder sandbox
@@ -46,3 +98,31 @@ Legend: +
additive, •
conditional.
|---|---|
|gcp-security-admins
group|[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) |
|prod-resman-sec-0
serviceAccount|[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder team a
+
+| members | roles |
+|---|---|
+|team-a
group|[roles/viewer](https://cloud.google.com/iam/docs/understanding-roles#viewer) |
+|prod-teams-team-a-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder team b
+
+| members | roles |
+|---|---|
+|prod-teams-team-b-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Folder teams
+
+| members | roles |
+|---|---|
+|prod-resman-teams-0
serviceAccount|[roles/compute.xpnAdmin](https://cloud.google.com/iam/docs/understanding-roles#compute.xpnAdmin)
[roles/logging.admin](https://cloud.google.com/iam/docs/understanding-roles#logging.admin)
[roles/owner](https://cloud.google.com/iam/docs/understanding-roles#owner)
[roles/resourcemanager.folderAdmin](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.folderAdmin)
[roles/resourcemanager.projectCreator](https://cloud.google.com/iam/docs/understanding-roles#resourcemanager.projectCreator) |
+
+## Project prod-iac-core-0
+
+| members | roles |
+|---|---|
+|dev-resman-dp-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +
|
+|dev-resman-gke-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +
|
+|prod-resman-gke-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +
|
+|prod-resman-net-1
serviceAccount|[roles/logging.logWriter](https://cloud.google.com/iam/docs/understanding-roles#logging.logWriter) +
|
diff --git a/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml
index d4df8cdc..3e2d9cc9 100644
--- a/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml
+++ b/fast/stages/02-networking-nva/data/firewall-rules/dev/rules.yaml
@@ -4,8 +4,8 @@ ingress-allow-composer-nodes:
description: "Allow traffic to Composer nodes."
direction: INGRESS
action: allow
- sources: []
- ranges: ["0.0.0.0/0"]
+ sources:
+ - composer-worker
targets:
- composer-worker
use_service_accounts: false
@@ -17,8 +17,8 @@ ingress-allow-dataflow-load:
description: "Allow traffic to Dataflow nodes."
direction: INGRESS
action: allow
- sources: []
- ranges: ["0.0.0.0/0"]
+ sources:
+ - dataflow
targets:
- dataflow
use_service_accounts: false
diff --git a/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml
index d4df8cdc..3e2d9cc9 100644
--- a/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml
+++ b/fast/stages/02-networking-peering/data/firewall-rules/dev/rules.yaml
@@ -4,8 +4,8 @@ ingress-allow-composer-nodes:
description: "Allow traffic to Composer nodes."
direction: INGRESS
action: allow
- sources: []
- ranges: ["0.0.0.0/0"]
+ sources:
+ - composer-worker
targets:
- composer-worker
use_service_accounts: false
@@ -17,8 +17,8 @@ ingress-allow-dataflow-load:
description: "Allow traffic to Dataflow nodes."
direction: INGRESS
action: allow
- sources: []
- ranges: ["0.0.0.0/0"]
+ sources:
+ - dataflow
targets:
- dataflow
use_service_accounts: false
diff --git a/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml b/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml
index d4df8cdc..3e2d9cc9 100644
--- a/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml
+++ b/fast/stages/02-networking-vpn/data/firewall-rules/dev/rules.yaml
@@ -4,8 +4,8 @@ ingress-allow-composer-nodes:
description: "Allow traffic to Composer nodes."
direction: INGRESS
action: allow
- sources: []
- ranges: ["0.0.0.0/0"]
+ sources:
+ - composer-worker
targets:
- composer-worker
use_service_accounts: false
@@ -17,8 +17,8 @@ ingress-allow-dataflow-load:
description: "Allow traffic to Dataflow nodes."
direction: INGRESS
action: allow
- sources: []
- ranges: ["0.0.0.0/0"]
+ sources:
+ - dataflow
targets:
- dataflow
use_service_accounts: false
diff --git a/fast/stages/03-data-platform/dev/demo b/fast/stages/03-data-platform/dev/demo
new file mode 120000
index 00000000..7a0e7c1e
--- /dev/null
+++ b/fast/stages/03-data-platform/dev/demo
@@ -0,0 +1 @@
+../../../../blueprints/data-solutions/data-platform-foundations/demo/
\ No newline at end of file
diff --git a/modules/__experimental/net-neg/versions.tf b/modules/__experimental/net-neg/versions.tf
index 4278054b..8abac788 100644
--- a/modules/__experimental/net-neg/versions.tf
+++ b/modules/__experimental/net-neg/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/api-gateway/versions.tf b/modules/api-gateway/versions.tf
index 4278054b..8abac788 100644
--- a/modules/api-gateway/versions.tf
+++ b/modules/api-gateway/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/apigee-organization/versions.tf b/modules/apigee-organization/versions.tf
index 4278054b..8abac788 100644
--- a/modules/apigee-organization/versions.tf
+++ b/modules/apigee-organization/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/apigee-x-instance/versions.tf b/modules/apigee-x-instance/versions.tf
index 4278054b..8abac788 100644
--- a/modules/apigee-x-instance/versions.tf
+++ b/modules/apigee-x-instance/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/artifact-registry/versions.tf b/modules/artifact-registry/versions.tf
index 4278054b..8abac788 100644
--- a/modules/artifact-registry/versions.tf
+++ b/modules/artifact-registry/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/bigquery-dataset/versions.tf b/modules/bigquery-dataset/versions.tf
index 4278054b..8abac788 100644
--- a/modules/bigquery-dataset/versions.tf
+++ b/modules/bigquery-dataset/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/bigtable-instance/versions.tf b/modules/bigtable-instance/versions.tf
index 4278054b..8abac788 100644
--- a/modules/bigtable-instance/versions.tf
+++ b/modules/bigtable-instance/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/billing-budget/versions.tf b/modules/billing-budget/versions.tf
index 4278054b..8abac788 100644
--- a/modules/billing-budget/versions.tf
+++ b/modules/billing-budget/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/binauthz/versions.tf b/modules/binauthz/versions.tf
index 4278054b..8abac788 100644
--- a/modules/binauthz/versions.tf
+++ b/modules/binauthz/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/coredns/versions.tf b/modules/cloud-config-container/coredns/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/coredns/versions.tf
+++ b/modules/cloud-config-container/coredns/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/cos-generic-metadata/versions.tf b/modules/cloud-config-container/cos-generic-metadata/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/cos-generic-metadata/versions.tf
+++ b/modules/cloud-config-container/cos-generic-metadata/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/envoy-traffic-director/versions.tf b/modules/cloud-config-container/envoy-traffic-director/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/envoy-traffic-director/versions.tf
+++ b/modules/cloud-config-container/envoy-traffic-director/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/mysql/versions.tf b/modules/cloud-config-container/mysql/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/mysql/versions.tf
+++ b/modules/cloud-config-container/mysql/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/nginx-tls/versions.tf b/modules/cloud-config-container/nginx-tls/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/nginx-tls/versions.tf
+++ b/modules/cloud-config-container/nginx-tls/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/nginx/versions.tf b/modules/cloud-config-container/nginx/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/nginx/versions.tf
+++ b/modules/cloud-config-container/nginx/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/onprem/versions.tf b/modules/cloud-config-container/onprem/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/onprem/versions.tf
+++ b/modules/cloud-config-container/onprem/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-config-container/squid/versions.tf b/modules/cloud-config-container/squid/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-config-container/squid/versions.tf
+++ b/modules/cloud-config-container/squid/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-function/versions.tf b/modules/cloud-function/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-function/versions.tf
+++ b/modules/cloud-function/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-identity-group/versions.tf b/modules/cloud-identity-group/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-identity-group/versions.tf
+++ b/modules/cloud-identity-group/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloud-run/versions.tf b/modules/cloud-run/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloud-run/versions.tf
+++ b/modules/cloud-run/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/cloudsql-instance/README.md b/modules/cloudsql-instance/README.md
index 2cbb09b9..bf2a12e4 100644
--- a/modules/cloudsql-instance/README.md
+++ b/modules/cloudsql-instance/README.md
@@ -151,7 +151,7 @@ module "db" {
| [network](variables.tf#L102) | VPC self link where the instances will be deployed. Private Service Networking must be enabled and configured in this VPC. | string
| ✓ | |
| [project_id](variables.tf#L113) | The ID of the project where this instances will be created. | string
| ✓ | |
| [region](variables.tf#L118) | Region of the primary instance. | string
| ✓ | |
-| [tier](variables.tf#L132) | The machine type to use for the instances. | string
| ✓ | |
+| [tier](variables.tf#L138) | The machine type to use for the instances. | string
| ✓ | |
| [authorized_networks](variables.tf#L17) | Map of NAME=>CIDR_RANGE to allow to connect to the database(s). | map(string)
| | null
|
| [availability_type](variables.tf#L23) | Availability type for the primary replica. Either `ZONAL` or `REGIONAL`. | string
| | "ZONAL"
|
| [backup_configuration](variables.tf#L29) | Backup settings for primary instance. Will be automatically enabled if using MySQL with one or more replicas. | object({…})
| | {…}
|
@@ -161,11 +161,12 @@ module "db" {
| [disk_type](variables.tf#L73) | The type of data disk: `PD_SSD` or `PD_HDD`. | string
| | "PD_SSD"
|
| [encryption_key_name](variables.tf#L79) | The full path to the encryption key used for the CMEK disk encryption of the primary instance. | string
| | null
|
| [flags](variables.tf#L85) | Map FLAG_NAME=>VALUE for database-specific tuning. | map(string)
| | null
|
-| [ipv4_enabled](variables.tf#L143) | Add a public IP address to database instance. | bool
| | false
|
+| [ipv4_enabled](variables.tf#L149) | Add a public IP address to database instance. | bool
| | false
|
| [labels](variables.tf#L91) | Labels to be attached to all instances. | map(string)
| | null
|
| [prefix](variables.tf#L107) | Prefix used to generate instance names. | string
| | null
|
| [replicas](variables.tf#L123) | Map of NAME=> {REGION, KMS_KEY} for additional read replicas. Set to null to disable replica creation. | map(object({…}))
| | {}
|
-| [users](variables.tf#L137) | Map of users to create in the primary instance (and replicated to other replicas) in the format USER=>PASSWORD. For MySQL, anything afterr the first `@` (if persent) will be used as the user's host. Set PASSWORD to null if you want to get an autogenerated password. | map(string)
| | null
|
+| [root_password](variables.tf#L132) | Root password of the Cloud SQL instance. Required for MS SQL Server | string
| | null
|
+| [users](variables.tf#L143) | Map of users to create in the primary instance (and replicated to other replicas) in the format USER=>PASSWORD. For MySQL, anything afterr the first `@` (if persent) will be used as the user's host. Set PASSWORD to null if you want to get an autogenerated password. | map(string)
| | null
|
## Outputs
diff --git a/modules/cloudsql-instance/main.tf b/modules/cloudsql-instance/main.tf
index de4b5560..f15b386b 100644
--- a/modules/cloudsql-instance/main.tf
+++ b/modules/cloudsql-instance/main.tf
@@ -18,10 +18,11 @@ locals {
prefix = var.prefix == null ? "" : "${var.prefix}-"
is_mysql = can(regex("^MYSQL", var.database_version))
has_replicas = try(length(var.replicas) > 0, false)
+ is_regional = var.availability_type == "REGIONAL" ? true : false
// Enable backup if the user asks for it or if the user is deploying
- // MySQL with replicas
- enable_backup = var.backup_configuration.enabled || (local.is_mysql && local.has_replicas)
+ // MySQL in HA configuration (regional or with specified replicas)
+ enable_backup = var.backup_configuration.enabled || (local.is_mysql && local.has_replicas) || (local.is_mysql && local.is_regional)
users = {
for user, password in coalesce(var.users, {}) :
@@ -49,6 +50,7 @@ resource "google_sql_database_instance" "primary" {
region = var.region
database_version = var.database_version
encryption_key_name = var.encryption_key_name
+ root_password = var.root_password
settings {
tier = var.tier
@@ -76,11 +78,11 @@ resource "google_sql_database_instance" "primary" {
content {
enabled = true
- // enable binary log if the user asks for it or we have replicas,
+ // enable binary log if the user asks for it or we have replicas (default in regional),
// but only for MySQL
binary_log_enabled = (
local.is_mysql
- ? var.backup_configuration.binary_log_enabled || local.has_replicas
+ ? var.backup_configuration.binary_log_enabled || local.has_replicas || local.is_regional
: null
)
start_time = var.backup_configuration.start_time
diff --git a/modules/cloudsql-instance/variables.tf b/modules/cloudsql-instance/variables.tf
index cd1581a2..05fbaf29 100644
--- a/modules/cloudsql-instance/variables.tf
+++ b/modules/cloudsql-instance/variables.tf
@@ -129,6 +129,12 @@ variable "replicas" {
default = {}
}
+variable "root_password" {
+ description = "Root password of the Cloud SQL instance. Required for MS SQL Server"
+ type = string
+ default = null
+}
+
variable "tier" {
description = "The machine type to use for the instances."
type = string
diff --git a/modules/cloudsql-instance/versions.tf b/modules/cloudsql-instance/versions.tf
index 4278054b..8abac788 100644
--- a/modules/cloudsql-instance/versions.tf
+++ b/modules/cloudsql-instance/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/compute-mig/versions.tf b/modules/compute-mig/versions.tf
index 4278054b..8abac788 100644
--- a/modules/compute-mig/versions.tf
+++ b/modules/compute-mig/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/compute-vm/main.tf b/modules/compute-vm/main.tf
index 8cbd4215..3a588160 100644
--- a/modules/compute-vm/main.tf
+++ b/modules/compute-vm/main.tf
@@ -311,6 +311,12 @@ resource "google_compute_instance_template" "default" {
config.value.source_type != "attach" ? config.value.name : null
)
type = "PERSISTENT"
+ dynamic "disk_encryption_key" {
+ for_each = var.encryption != null ? [""] : []
+ content {
+ kms_key_self_link = var.encryption.kms_key_self_link
+ }
+ }
}
}
diff --git a/modules/compute-vm/versions.tf b/modules/compute-vm/versions.tf
index 4278054b..8abac788 100644
--- a/modules/compute-vm/versions.tf
+++ b/modules/compute-vm/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/container-registry/versions.tf b/modules/container-registry/versions.tf
index 4278054b..8abac788 100644
--- a/modules/container-registry/versions.tf
+++ b/modules/container-registry/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/data-catalog-policy-tag/versions.tf b/modules/data-catalog-policy-tag/versions.tf
index 4278054b..8abac788 100644
--- a/modules/data-catalog-policy-tag/versions.tf
+++ b/modules/data-catalog-policy-tag/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/datafusion/versions.tf b/modules/datafusion/versions.tf
index 4278054b..8abac788 100644
--- a/modules/datafusion/versions.tf
+++ b/modules/datafusion/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/dns/versions.tf b/modules/dns/versions.tf
index 4278054b..8abac788 100644
--- a/modules/dns/versions.tf
+++ b/modules/dns/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/endpoints/versions.tf b/modules/endpoints/versions.tf
index 4278054b..8abac788 100644
--- a/modules/endpoints/versions.tf
+++ b/modules/endpoints/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/folder/versions.tf b/modules/folder/versions.tf
index 4278054b..8abac788 100644
--- a/modules/folder/versions.tf
+++ b/modules/folder/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gcs/versions.tf b/modules/gcs/versions.tf
index 4278054b..8abac788 100644
--- a/modules/gcs/versions.tf
+++ b/modules/gcs/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gke-cluster/README.md b/modules/gke-cluster/README.md
index 20a3f2fc..a34b72b9 100644
--- a/modules/gke-cluster/README.md
+++ b/modules/gke-cluster/README.md
@@ -68,13 +68,13 @@ module "cluster-1" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [location](variables.tf#L155) | Cluster zone or region. | string
| ✓ | |
-| [name](variables.tf#L222) | Cluster name. | string
| ✓ | |
-| [network](variables.tf#L227) | Name or self link of the VPC used for the cluster. Use the self link for Shared VPC. | string
| ✓ | |
-| [project_id](variables.tf#L271) | Cluster project id. | string
| ✓ | |
-| [secondary_range_pods](variables.tf#L294) | Subnet secondary range name used for pods. | string
| ✓ | |
-| [secondary_range_services](variables.tf#L299) | Subnet secondary range name used for services. | string
| ✓ | |
-| [subnetwork](variables.tf#L304) | VPC subnetwork name or self link. | string
| ✓ | |
+| [location](variables.tf#L161) | Cluster zone or region. | string
| ✓ | |
+| [name](variables.tf#L228) | Cluster name. | string
| ✓ | |
+| [network](variables.tf#L233) | Name or self link of the VPC used for the cluster. Use the self link for Shared VPC. | string
| ✓ | |
+| [project_id](variables.tf#L277) | Cluster project id. | string
| ✓ | |
+| [secondary_range_pods](variables.tf#L300) | Subnet secondary range name used for pods. | string
| ✓ | |
+| [secondary_range_services](variables.tf#L305) | Subnet secondary range name used for services. | string
| ✓ | |
+| [subnetwork](variables.tf#L310) | VPC subnetwork name or self link. | string
| ✓ | |
| [addons](variables.tf#L17) | Addons enabled in the cluster (true means enabled). | object({…})
| | {…}
|
| [authenticator_security_group](variables.tf#L53) | RBAC security group for Google Groups for GKE, format is gke-security-groups@yourdomain.com. | string
| | null
|
| [cluster_autoscaling](variables.tf#L59) | Enable and configure limits for Node Auto-Provisioning with Cluster Autoscaler. | object({…})
| | {…}
|
@@ -83,28 +83,29 @@ module "cluster-1" {
| [description](variables.tf#L97) | Cluster description. | string
| | null
|
| [dns_config](variables.tf#L103) | Configuration for Using Cloud DNS for GKE. | object({…})
| | null
|
| [enable_autopilot](variables.tf#L113) | Create cluster in autopilot mode. With autopilot there's no need to create node-pools and some features are not supported (e.g. setting default_max_pods_per_node). | bool
| | false
|
-| [enable_dataplane_v2](variables.tf#L119) | Enable Dataplane V2 on the cluster, will disable network_policy addons config. | bool
| | false
|
-| [enable_intranode_visibility](variables.tf#L125) | Enable intra-node visibility to make same node pod to pod traffic visible. | bool
| | null
|
-| [enable_l4_ilb_subsetting](variables.tf#L131) | Enable L4ILB Subsetting. | bool
| | null
|
-| [enable_shielded_nodes](variables.tf#L137) | Enable Shielded Nodes features on all nodes in this cluster. | bool
| | null
|
-| [enable_tpu](variables.tf#L143) | Enable Cloud TPU resources in this cluster. | bool
| | null
|
-| [labels](variables.tf#L149) | Cluster resource labels. | map(string)
| | null
|
-| [logging_config](variables.tf#L160) | Logging configuration (enabled components). | list(string)
| | null
|
-| [logging_service](variables.tf#L166) | Logging service (disable with an empty string). | string
| | "logging.googleapis.com/kubernetes"
|
-| [maintenance_config](variables.tf#L172) | Maintenance window configuration. | object({…})
| | {…}
|
-| [master_authorized_ranges](variables.tf#L198) | External Ip address ranges that can access the Kubernetes cluster master through HTTPS. | map(string)
| | {}
|
-| [min_master_version](variables.tf#L204) | Minimum version of the master, defaults to the version of the most recent official release. | string
| | null
|
-| [monitoring_config](variables.tf#L210) | Monitoring configuration (enabled components). | list(string)
| | null
|
-| [monitoring_service](variables.tf#L216) | Monitoring service (disable with an empty string). | string
| | "monitoring.googleapis.com/kubernetes"
|
-| [node_locations](variables.tf#L232) | Zones in which the cluster's nodes are located. | list(string)
| | []
|
-| [notification_config](variables.tf#L238) | GKE Cluster upgrade notifications via PubSub. | bool
| | false
|
-| [peering_config](variables.tf#L244) | Configure peering with the master VPC for private clusters. | object({…})
| | null
|
-| [pod_security_policy](variables.tf#L254) | Enable the PodSecurityPolicy feature. | bool
| | null
|
-| [private_cluster_config](variables.tf#L260) | Enable and configure private cluster, private nodes must be true if used. | object({…})
| | null
|
-| [release_channel](variables.tf#L276) | Release channel for GKE upgrades. | string
| | null
|
-| [resource_usage_export_config](variables.tf#L282) | Configure the ResourceUsageExportConfig feature. | object({…})
| | {…}
|
-| [vertical_pod_autoscaling](variables.tf#L309) | Enable the Vertical Pod Autoscaling feature. | bool
| | null
|
-| [workload_identity](variables.tf#L315) | Enable the Workload Identity feature. | bool
| | true
|
+| [enable_binary_authorization](variables.tf#L119) | Enable Google Binary Authorization. | bool
| | false
|
+| [enable_dataplane_v2](variables.tf#L125) | Enable Dataplane V2 on the cluster, will disable network_policy addons config. | bool
| | false
|
+| [enable_intranode_visibility](variables.tf#L131) | Enable intra-node visibility to make same node pod to pod traffic visible. | bool
| | null
|
+| [enable_l4_ilb_subsetting](variables.tf#L137) | Enable L4ILB Subsetting. | bool
| | null
|
+| [enable_shielded_nodes](variables.tf#L143) | Enable Shielded Nodes features on all nodes in this cluster. | bool
| | null
|
+| [enable_tpu](variables.tf#L149) | Enable Cloud TPU resources in this cluster. | bool
| | null
|
+| [labels](variables.tf#L155) | Cluster resource labels. | map(string)
| | null
|
+| [logging_config](variables.tf#L166) | Logging configuration (enabled components). | list(string)
| | null
|
+| [logging_service](variables.tf#L172) | Logging service (disable with an empty string). | string
| | "logging.googleapis.com/kubernetes"
|
+| [maintenance_config](variables.tf#L178) | Maintenance window configuration. | object({…})
| | {…}
|
+| [master_authorized_ranges](variables.tf#L204) | External Ip address ranges that can access the Kubernetes cluster master through HTTPS. | map(string)
| | {}
|
+| [min_master_version](variables.tf#L210) | Minimum version of the master, defaults to the version of the most recent official release. | string
| | null
|
+| [monitoring_config](variables.tf#L216) | Monitoring configuration (enabled components). | list(string)
| | null
|
+| [monitoring_service](variables.tf#L222) | Monitoring service (disable with an empty string). | string
| | "monitoring.googleapis.com/kubernetes"
|
+| [node_locations](variables.tf#L238) | Zones in which the cluster's nodes are located. | list(string)
| | []
|
+| [notification_config](variables.tf#L244) | GKE Cluster upgrade notifications via PubSub. | bool
| | false
|
+| [peering_config](variables.tf#L250) | Configure peering with the master VPC for private clusters. | object({…})
| | null
|
+| [pod_security_policy](variables.tf#L260) | Enable the PodSecurityPolicy feature. | bool
| | null
|
+| [private_cluster_config](variables.tf#L266) | Enable and configure private cluster, private nodes must be true if used. | object({…})
| | null
|
+| [release_channel](variables.tf#L282) | Release channel for GKE upgrades. | string
| | null
|
+| [resource_usage_export_config](variables.tf#L288) | Configure the ResourceUsageExportConfig feature. | object({…})
| | {…}
|
+| [vertical_pod_autoscaling](variables.tf#L315) | Enable the Vertical Pod Autoscaling feature. | bool
| | null
|
+| [workload_identity](variables.tf#L321) | Enable the Workload Identity feature. | bool
| | true
|
## Outputs
diff --git a/modules/gke-cluster/main.tf b/modules/gke-cluster/main.tf
index 56f7ea75..e0b31a31 100644
--- a/modules/gke-cluster/main.tf
+++ b/modules/gke-cluster/main.tf
@@ -292,6 +292,13 @@ resource "google_container_cluster" "cluster" {
}
}
+ dynamic "binary_authorization" {
+ for_each = var.enable_binary_authorization ? [""] : []
+ content {
+ evaluation_mode = "PROJECT_SINGLETON_POLICY_ENFORCE"
+ }
+ }
+
dynamic "dns_config" {
for_each = var.dns_config != null ? [""] : []
content {
diff --git a/modules/gke-cluster/variables.tf b/modules/gke-cluster/variables.tf
index 58be03c9..2c9fccbe 100644
--- a/modules/gke-cluster/variables.tf
+++ b/modules/gke-cluster/variables.tf
@@ -116,6 +116,12 @@ variable "enable_autopilot" {
default = false
}
+variable "enable_binary_authorization" {
+ description = "Enable Google Binary Authorization."
+ type = bool
+ default = false
+}
+
variable "enable_dataplane_v2" {
description = "Enable Dataplane V2 on the cluster, will disable network_policy addons config."
type = bool
diff --git a/modules/gke-cluster/versions.tf b/modules/gke-cluster/versions.tf
index 4278054b..8abac788 100644
--- a/modules/gke-cluster/versions.tf
+++ b/modules/gke-cluster/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gke-hub/versions.tf b/modules/gke-hub/versions.tf
index 4278054b..8abac788 100644
--- a/modules/gke-hub/versions.tf
+++ b/modules/gke-hub/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/gke-nodepool/versions.tf b/modules/gke-nodepool/versions.tf
index 4278054b..8abac788 100644
--- a/modules/gke-nodepool/versions.tf
+++ b/modules/gke-nodepool/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/iam-service-account/versions.tf b/modules/iam-service-account/versions.tf
index 4278054b..8abac788 100644
--- a/modules/iam-service-account/versions.tf
+++ b/modules/iam-service-account/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/kms/versions.tf b/modules/kms/versions.tf
index 4278054b..8abac788 100644
--- a/modules/kms/versions.tf
+++ b/modules/kms/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/logging-bucket/versions.tf b/modules/logging-bucket/versions.tf
index 4278054b..8abac788 100644
--- a/modules/logging-bucket/versions.tf
+++ b/modules/logging-bucket/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-address/README.md b/modules/net-address/README.md
index 76637ccd..e5138348 100644
--- a/modules/net-address/README.md
+++ b/modules/net-address/README.md
@@ -27,22 +27,16 @@ module "addresses" {
project_id = var.project_id
internal_addresses = {
ilb-1 = {
+ purpose = "SHARED_LOADBALANCER_VIP"
region = var.region
subnetwork = var.subnet.self_link
}
ilb-2 = {
+ address = "10.0.0.2"
region = var.region
subnetwork = var.subnet.self_link
}
}
- # optional configuration
- internal_addresses_config = {
- ilb-1 = {
- address = null
- purpose = "SHARED_LOADBALANCER_VIP"
- tier = null
- }
- }
}
# tftest modules=1 resources=2
```
@@ -89,13 +83,12 @@ module "addresses" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [project_id](variables.tf#L60) | Project where the addresses will be created. | string
| ✓ | |
+| [project_id](variables.tf#L54) | Project where the addresses will be created. | string
| ✓ | |
| [external_addresses](variables.tf#L17) | Map of external address regions, keyed by name. | map(string)
| | {}
|
| [global_addresses](variables.tf#L29) | List of global addresses to create. | list(string)
| | []
|
-| [internal_addresses](variables.tf#L35) | Map of internal addresses to create, keyed by name. | map(object({…}))
| | {}
|
-| [internal_addresses_config](variables.tf#L44) | Optional configuration for internal addresses, keyed by name. Unused options can be set to null. | map(object({…}))
| | {}
|
-| [psa_addresses](variables.tf#L65) | Map of internal addresses used for Private Service Access. | map(object({…}))
| | {}
|
-| [psc_addresses](variables.tf#L75) | Map of internal addresses used for Private Service Connect. | map(object({…}))
| | {}
|
+| [internal_addresses](variables.tf#L35) | Map of internal addresses to create, keyed by name. | map(object({…}))
| | {}
|
+| [psa_addresses](variables.tf#L59) | Map of internal addresses used for Private Service Access. | map(object({…}))
| | {}
|
+| [psc_addresses](variables.tf#L69) | Map of internal addresses used for Private Service Connect. | map(object({…}))
| | {}
|
## Outputs
diff --git a/modules/net-address/main.tf b/modules/net-address/main.tf
index caab92a0..8619f95b 100644
--- a/modules/net-address/main.tf
+++ b/modules/net-address/main.tf
@@ -39,10 +39,10 @@ resource "google_compute_address" "internal" {
address_type = "INTERNAL"
region = each.value.region
subnetwork = each.value.subnetwork
- address = try(var.internal_addresses_config[each.key].address, null)
- network_tier = try(var.internal_addresses_config[each.key].tier, null)
- purpose = try(var.internal_addresses_config[each.key].purpose, null)
- # labels = lookup(var.internal_address_labels, each.key, {})
+ address = each.value.address
+ network_tier = each.value.tier
+ purpose = each.value.purpose
+ labels = coalesce(each.value.labels, {})
}
resource "google_compute_global_address" "psc" {
diff --git a/modules/net-address/variables.tf b/modules/net-address/variables.tf
index bb3043dc..35093e83 100644
--- a/modules/net-address/variables.tf
+++ b/modules/net-address/variables.tf
@@ -37,16 +37,10 @@ variable "internal_addresses" {
type = map(object({
region = string
subnetwork = string
- }))
- default = {}
-}
-
-variable "internal_addresses_config" {
- description = "Optional configuration for internal addresses, keyed by name. Unused options can be set to null."
- type = map(object({
- address = string
- purpose = string
- tier = string
+ address = optional(string)
+ labels = optional(map(string))
+ purpose = optional(string)
+ tier = optional(string)
}))
default = {}
}
diff --git a/modules/net-address/versions.tf b/modules/net-address/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-address/versions.tf
+++ b/modules/net-address/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-cloudnat/versions.tf b/modules/net-cloudnat/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-cloudnat/versions.tf
+++ b/modules/net-cloudnat/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-glb/versions.tf b/modules/net-glb/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-glb/versions.tf
+++ b/modules/net-glb/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-ilb-l7/README.md b/modules/net-ilb-l7/README.md
index 5dabc52d..64a3f776 100644
--- a/modules/net-ilb-l7/README.md
+++ b/modules/net-ilb-l7/README.md
@@ -403,18 +403,18 @@ An Internal HTTP Load Balancer is made of multiple components, that change depen
|---|---|:---:|:---:|:---:|
| [name](variables.tf#L17) | Load balancer name. | string
| ✓ | |
| [project_id](variables.tf#L22) | Project id. | string
| ✓ | |
-| [region](variables.tf#L157) | The region where to allocate the ILB resources. | string
| ✓ | |
-| [subnetwork](variables.tf#L187) | The subnetwork where the ILB VIP is allocated. | string
| ✓ | |
+| [region](variables.tf#L159) | The region where to allocate the ILB resources. | string
| ✓ | |
+| [subnetwork](variables.tf#L189) | The subnetwork where the ILB VIP is allocated. | string
| ✓ | |
| [backend_services_config](variables.tf#L27) | The backends services configuration. | map(object({…}))
| | {}
|
-| [forwarding_rule_config](variables.tf#L98) | Forwarding rule configurations. | object({…})
| | {…}
|
-| [health_checks_config](variables.tf#L116) | Custom health checks configuration. | map(object({…}))
| | {}
|
-| [health_checks_config_defaults](variables.tf#L127) | Auto-created health check default configuration. | object({…})
| | {…}
|
-| [https](variables.tf#L145) | Whether to enable HTTPS. | bool
| | false
|
-| [network](variables.tf#L151) | The network where the ILB is created. | string
| | "default"
|
-| [ssl_certificates_config](variables.tf#L162) | The SSL certificates configuration. | map(object({…}))
| | {}
|
-| [static_ip_config](variables.tf#L172) | Static IP address configuration. | object({…})
| | {…}
|
-| [target_proxy_https_config](variables.tf#L192) | The HTTPS target proxy configuration. | object({…})
| | null
|
-| [url_map_config](variables.tf#L200) | The url-map configuration. | object({…})
| | null
|
+| [forwarding_rule_config](variables.tf#L98) | Forwarding rule configurations. | object({…})
| | {…}
|
+| [health_checks_config](variables.tf#L118) | Custom health checks configuration. | map(object({…}))
| | {}
|
+| [health_checks_config_defaults](variables.tf#L129) | Auto-created health check default configuration. | object({…})
| | {…}
|
+| [https](variables.tf#L147) | Whether to enable HTTPS. | bool
| | false
|
+| [network](variables.tf#L153) | The network where the ILB is created. | string
| | "default"
|
+| [ssl_certificates_config](variables.tf#L164) | The SSL certificates configuration. | map(object({…}))
| | {}
|
+| [static_ip_config](variables.tf#L174) | Static IP address configuration. | object({…})
| | {…}
|
+| [target_proxy_https_config](variables.tf#L194) | The HTTPS target proxy configuration. | object({…})
| | null
|
+| [url_map_config](variables.tf#L202) | The url-map configuration. | object({…})
| | null
|
## Outputs
diff --git a/modules/net-ilb-l7/forwarding-rule.tf b/modules/net-ilb-l7/forwarding-rule.tf
index 41044060..31ff6525 100644
--- a/modules/net-ilb-l7/forwarding-rule.tf
+++ b/modules/net-ilb-l7/forwarding-rule.tf
@@ -62,6 +62,7 @@ resource "google_compute_forwarding_rule" "forwarding_rule" {
port_range = local.port_range
ports = []
region = try(var.region, null)
+ service_label = try(var.forwarding_rule_config.service_label, null)
subnetwork = try(var.subnetwork, null)
target = local.target
}
diff --git a/modules/net-ilb-l7/variables.tf b/modules/net-ilb-l7/variables.tf
index 8d9979fd..7202e3fa 100644
--- a/modules/net-ilb-l7/variables.tf
+++ b/modules/net-ilb-l7/variables.tf
@@ -98,10 +98,11 @@ variable "backend_services_config" {
variable "forwarding_rule_config" {
description = "Forwarding rule configurations."
type = object({
- ip_version = string
- labels = map(string)
- network_tier = string
- port_range = string
+ ip_version = string
+ labels = map(string)
+ network_tier = string
+ port_range = string
+ service_label = string
})
default = {
allow_global_access = true
@@ -109,7 +110,8 @@ variable "forwarding_rule_config" {
labels = {}
network_tier = "PREMIUM"
# If not specified, 443 if var.https = true; 80 otherwise
- port_range = null
+ port_range = null
+ service_label = null
}
}
diff --git a/modules/net-ilb-l7/versions.tf b/modules/net-ilb-l7/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-ilb-l7/versions.tf
+++ b/modules/net-ilb-l7/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-ilb/versions.tf b/modules/net-ilb/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-ilb/versions.tf
+++ b/modules/net-ilb/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-interconnect-attachment-direct/versions.tf b/modules/net-interconnect-attachment-direct/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-interconnect-attachment-direct/versions.tf
+++ b/modules/net-interconnect-attachment-direct/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpc-firewall/versions.tf b/modules/net-vpc-firewall/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-vpc-firewall/versions.tf
+++ b/modules/net-vpc-firewall/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpc-peering/versions.tf b/modules/net-vpc-peering/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-vpc-peering/versions.tf
+++ b/modules/net-vpc-peering/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpc/versions.tf b/modules/net-vpc/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-vpc/versions.tf
+++ b/modules/net-vpc/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpn-dynamic/versions.tf b/modules/net-vpn-dynamic/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-vpn-dynamic/versions.tf
+++ b/modules/net-vpn-dynamic/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpn-ha/versions.tf b/modules/net-vpn-ha/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-vpn-ha/versions.tf
+++ b/modules/net-vpn-ha/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/net-vpn-static/versions.tf b/modules/net-vpn-static/versions.tf
index 4278054b..8abac788 100644
--- a/modules/net-vpn-static/versions.tf
+++ b/modules/net-vpn-static/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/organization-policy/versions.tf b/modules/organization-policy/versions.tf
index 4278054b..8abac788 100644
--- a/modules/organization-policy/versions.tf
+++ b/modules/organization-policy/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/organization/versions.tf b/modules/organization/versions.tf
index 4278054b..8abac788 100644
--- a/modules/organization/versions.tf
+++ b/modules/organization/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/project/README.md b/modules/project/README.md
index 8ce143bb..64ee2d4f 100644
--- a/modules/project/README.md
+++ b/modules/project/README.md
@@ -352,7 +352,7 @@ output "compute_robot" {
| [main.tf](./main.tf) | Module-level locals and resources. | google_compute_project_metadata_item
· google_essential_contacts_contact
· google_monitoring_monitored_project
· google_project
· google_project_service
· google_resource_manager_lien
|
| [organization-policies.tf](./organization-policies.tf) | Project-level organization policies. | google_project_organization_policy
|
| [outputs.tf](./outputs.tf) | Module outputs. | |
-| [service-accounts.tf](./service-accounts.tf) | Service identities and supporting resources. | google_kms_crypto_key_iam_member
· google_project_iam_member
· google_project_service_identity
|
+| [service-accounts.tf](./service-accounts.tf) | Service identities and supporting resources. | google_kms_crypto_key_iam_member
· google_project_default_service_accounts
· google_project_iam_member
· google_project_service_identity
|
| [shared-vpc.tf](./shared-vpc.tf) | Shared VPC project-level configuration. | google_compute_shared_vpc_host_project
· google_compute_shared_vpc_service_project
· google_project_iam_member
|
| [tags.tf](./tags.tf) | None | google_tags_tag_binding
|
| [variables.tf](./variables.tf) | Module variables. | |
@@ -363,38 +363,39 @@ output "compute_robot" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [name](variables.tf#L125) | Project name and id suffix. | string
| ✓ | |
+| [name](variables.tf#L131) | Project name and id suffix. | string
| ✓ | |
| [auto_create_network](variables.tf#L17) | Whether to create the default network for the project. | bool
| | false
|
| [billing_account](variables.tf#L23) | Billing account id. | string
| | null
|
| [contacts](variables.tf#L29) | 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#L36) | Map of role name => list of permissions to create in this project. | map(list(string))
| | {}
|
+| [default_service_account](variables.tf#L49) | Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`. | string
| | "keep"
|
| [descriptive_name](variables.tf#L43) | Name of the project name. Used for project name instead of `name` variable. | string
| | null
|
-| [group_iam](variables.tf#L49) | 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#L56) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string))
| | {}
|
-| [iam_additive](variables.tf#L63) | IAM additive bindings in {ROLE => [MEMBERS]} format. | map(list(string))
| | {}
|
-| [iam_additive_members](variables.tf#L70) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string))
| | {}
|
-| [labels](variables.tf#L76) | Resource labels. | map(string)
| | {}
|
-| [lien_reason](variables.tf#L83) | If non-empty, creates a project lien with this description. | string
| | ""
|
-| [logging_exclusions](variables.tf#L89) | Logging exclusions for this project in the form {NAME -> FILTER}. | map(string)
| | {}
|
-| [logging_sinks](variables.tf#L96) | Logging sinks to create for this project. | map(object({…}))
| | {}
|
-| [metric_scopes](variables.tf#L118) | List of projects that will act as metric scopes for this project. | list(string)
| | []
|
-| [oslogin](variables.tf#L130) | Enable OS Login. | bool
| | false
|
-| [oslogin_admins](variables.tf#L136) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | list(string)
| | []
|
-| [oslogin_users](variables.tf#L144) | List of IAM-style identities that will be granted roles necessary for OS Login users. | list(string)
| | []
|
-| [parent](variables.tf#L151) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string
| | null
|
-| [policy_boolean](variables.tf#L161) | Map of boolean org policies and enforcement value, set value to null for policy restore. | map(bool)
| | {}
|
-| [policy_list](variables.tf#L168) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | map(object({…}))
| | {}
|
-| [prefix](variables.tf#L180) | Prefix used to generate project id and name. | string
| | null
|
-| [project_create](variables.tf#L186) | Create project. When set to false, uses a data source to reference existing project. | bool
| | true
|
-| [service_config](variables.tf#L192) | Configure service API activation. | object({…})
| | {…}
|
-| [service_encryption_key_ids](variables.tf#L204) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | map(list(string))
| | {}
|
-| [service_perimeter_bridges](variables.tf#L211) | 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#L218) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | string
| | null
|
-| [services](variables.tf#L224) | Service APIs to enable. | list(string)
| | []
|
-| [shared_vpc_host_config](variables.tf#L230) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…})
| | null
|
-| [shared_vpc_service_config](variables.tf#L239) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…})
| | null
|
-| [skip_delete](variables.tf#L249) | Allows the underlying resources to be destroyed without destroying the project itself. | bool
| | false
|
-| [tag_bindings](variables.tf#L255) | Tag bindings for this project, in key => tag value id format. | map(string)
| | null
|
+| [group_iam](variables.tf#L55) | 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#L62) | IAM bindings in {ROLE => [MEMBERS]} format. | map(list(string))
| | {}
|
+| [iam_additive](variables.tf#L69) | IAM additive bindings in {ROLE => [MEMBERS]} format. | map(list(string))
| | {}
|
+| [iam_additive_members](variables.tf#L76) | IAM additive bindings in {MEMBERS => [ROLE]} format. This might break if members are dynamic values. | map(list(string))
| | {}
|
+| [labels](variables.tf#L82) | Resource labels. | map(string)
| | {}
|
+| [lien_reason](variables.tf#L89) | If non-empty, creates a project lien with this description. | string
| | ""
|
+| [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#L124) | List of projects that will act as metric scopes for this project. | list(string)
| | []
|
+| [oslogin](variables.tf#L136) | Enable OS Login. | bool
| | false
|
+| [oslogin_admins](variables.tf#L142) | List of IAM-style identities that will be granted roles necessary for OS Login administrators. | list(string)
| | []
|
+| [oslogin_users](variables.tf#L150) | List of IAM-style identities that will be granted roles necessary for OS Login users. | list(string)
| | []
|
+| [parent](variables.tf#L157) | Parent folder or organization in 'folders/folder_id' or 'organizations/org_id' format. | string
| | null
|
+| [policy_boolean](variables.tf#L167) | Map of boolean org policies and enforcement value, set value to null for policy restore. | map(bool)
| | {}
|
+| [policy_list](variables.tf#L174) | Map of list org policies, status is true for allow, false for deny, null for restore. Values can only be used for allow or deny. | map(object({…}))
| | {}
|
+| [prefix](variables.tf#L186) | Prefix used to generate project id and name. | string
| | null
|
+| [project_create](variables.tf#L192) | Create project. When set to false, uses a data source to reference existing project. | bool
| | true
|
+| [service_config](variables.tf#L198) | Configure service API activation. | object({…})
| | {…}
|
+| [service_encryption_key_ids](variables.tf#L210) | Cloud KMS encryption key in {SERVICE => [KEY_URL]} format. | map(list(string))
| | {}
|
+| [service_perimeter_bridges](variables.tf#L217) | 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#L224) | Name of VPC-SC Standard perimeter to add project into. See comment in the variables file for format. | string
| | null
|
+| [services](variables.tf#L230) | Service APIs to enable. | list(string)
| | []
|
+| [shared_vpc_host_config](variables.tf#L236) | Configures this project as a Shared VPC host project (mutually exclusive with shared_vpc_service_project). | object({…})
| | null
|
+| [shared_vpc_service_config](variables.tf#L245) | Configures this project as a Shared VPC service project (mutually exclusive with shared_vpc_host_config). | object({…})
| | null
|
+| [skip_delete](variables.tf#L255) | Allows the underlying resources to be destroyed without destroying the project itself. | bool
| | false
|
+| [tag_bindings](variables.tf#L261) | Tag bindings for this project, in key => tag value id format. | map(string)
| | null
|
## Outputs
diff --git a/modules/project/service-accounts.tf b/modules/project/service-accounts.tf
index 7d584fa7..f6da4fbf 100644
--- a/modules/project/service-accounts.tf
+++ b/modules/project/service-accounts.tf
@@ -67,6 +67,7 @@ locals {
}
)
service_accounts_jit_services = [
+ "artifactregistry.googleapis.com",
"cloudasset.googleapis.com",
"gkehub.googleapis.com",
"pubsub.googleapis.com",
@@ -139,3 +140,11 @@ resource "google_kms_crypto_key_iam_member" "service_identity_cmek" {
data.google_storage_project_service_account.gcs_sa,
]
}
+
+resource "google_project_default_service_accounts" "default_service_accounts" {
+ count = upper(var.default_service_account) == "KEEP" ? 0 : 1
+ action = upper(var.default_service_account)
+ project = local.project.project_id
+ restore_policy = "REVERT_AND_IGNORE_FAILURE"
+ depends_on = [google_project_service.project_services]
+}
diff --git a/modules/project/variables.tf b/modules/project/variables.tf
index 9268deb2..30eff53a 100644
--- a/modules/project/variables.tf
+++ b/modules/project/variables.tf
@@ -46,6 +46,12 @@ variable "descriptive_name" {
default = null
}
+variable "default_service_account" {
+ description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."
+ default = "keep"
+ type = string
+}
+
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))
diff --git a/modules/project/versions.tf b/modules/project/versions.tf
index 4278054b..8abac788 100644
--- a/modules/project/versions.tf
+++ b/modules/project/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/projects-data-source/versions.tf b/modules/projects-data-source/versions.tf
index 4278054b..8abac788 100644
--- a/modules/projects-data-source/versions.tf
+++ b/modules/projects-data-source/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/pubsub/versions.tf b/modules/pubsub/versions.tf
index 4278054b..8abac788 100644
--- a/modules/pubsub/versions.tf
+++ b/modules/pubsub/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/secret-manager/versions.tf b/modules/secret-manager/versions.tf
index 4278054b..8abac788 100644
--- a/modules/secret-manager/versions.tf
+++ b/modules/secret-manager/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/service-directory/versions.tf b/modules/service-directory/versions.tf
index 4278054b..8abac788 100644
--- a/modules/service-directory/versions.tf
+++ b/modules/service-directory/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/source-repository/versions.tf b/modules/source-repository/versions.tf
index 4278054b..8abac788 100644
--- a/modules/source-repository/versions.tf
+++ b/modules/source-repository/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/modules/vpc-sc/versions.tf b/modules/vpc-sc/versions.tf
index 4278054b..8abac788 100644
--- a/modules/vpc-sc/versions.tf
+++ b/modules/vpc-sc/versions.tf
@@ -13,7 +13,7 @@
# limitations under the License.
terraform {
- required_version = ">= 1.1.0"
+ required_version = ">= 1.3.0"
required_providers {
google = {
source = "hashicorp/google"
diff --git a/tests/modules/organization_policy/fixture/experimental.tf b/tests/blueprints/data_solutions/composer_2/__init__.py
similarity index 69%
rename from tests/modules/organization_policy/fixture/experimental.tf
rename to tests/blueprints/data_solutions/composer_2/__init__.py
index 6ed0c934..6d6d1266 100644
--- a/tests/modules/organization_policy/fixture/experimental.tf
+++ b/tests/blueprints/data_solutions/composer_2/__init__.py
@@ -4,15 +4,10 @@
# 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
+# 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.
-
-terraform {
- # TODO: Remove once Terraform 1.3 is released https://github.com/hashicorp/terraform/releases/tag/v1.3.0-alpha20220622
- experiments = [module_variable_optional_attrs]
-}
diff --git a/tests/blueprints/data_solutions/composer_2/fixture/main.tf b/tests/blueprints/data_solutions/composer_2/fixture/main.tf
new file mode 100644
index 00000000..4b35e6f8
--- /dev/null
+++ b/tests/blueprints/data_solutions/composer_2/fixture/main.tf
@@ -0,0 +1,26 @@
+/**
+ * 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/modules/organization-policy/experimental.tf b/tests/blueprints/data_solutions/composer_2/test_plan.py
similarity index 67%
rename from modules/organization-policy/experimental.tf
rename to tests/blueprints/data_solutions/composer_2/test_plan.py
index 5fc3fc44..04f4a39f 100644
--- a/modules/organization-policy/experimental.tf
+++ b/tests/blueprints/data_solutions/composer_2/test_plan.py
@@ -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
#
-# https://www.apache.org/licenses/LICENSE-2.0
+# 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,
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-terraform {
- # TODO: Remove once Terraform 1.3 is released https://github.com/hashicorp/terraform/releases/tag/v1.3.0-alpha20220622
- experiments = [module_variable_optional_attrs]
-}
+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/test_plan.py b/tests/blueprints/data_solutions/data_platform_foundations/test_plan.py
index e5db6ffc..0e4b77f5 100644
--- a/tests/blueprints/data_solutions/data_platform_foundations/test_plan.py
+++ b/tests/blueprints/data_solutions/data_platform_foundations/test_plan.py
@@ -24,4 +24,4 @@ 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) == 41
- assert len(resources) == 313
+ assert len(resources) == 314
diff --git a/tests/blueprints/gke/binauthz/test_plan.py b/tests/blueprints/gke/binauthz/test_plan.py
index 6e176b1c..cf012c06 100644
--- a/tests/blueprints/gke/binauthz/test_plan.py
+++ b/tests/blueprints/gke/binauthz/test_plan.py
@@ -16,4 +16,4 @@ 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) == 42
+ assert len(resources) == 43
diff --git a/tests/modules/cloudsql_instance/test_plan.py b/tests/modules/cloudsql_instance/test_plan.py
index f23c69c7..72d31dad 100644
--- a/tests/modules/cloudsql_instance/test_plan.py
+++ b/tests/modules/cloudsql_instance/test_plan.py
@@ -90,6 +90,17 @@ def test_mysql_replicas_enables_backup(plan_runner):
assert backup_config['binary_log_enabled']
+def test_mysql_binary_log_for_regional(plan_runner):
+ "Test that the binary log will be enabled for regional MySQL DBs."
+
+ _, resources = plan_runner(database_version="MYSQL_8_0", availability_type="REGIONAL")
+ assert len(resources) == 1
+ primary = [r for r in resources if r['name'] == 'primary'][0]
+ backup_config = primary['values']['settings'][0]['backup_configuration'][0]
+ assert backup_config['enabled']
+ assert backup_config['binary_log_enabled']
+
+
def test_users(plan_runner):
"Test user creation."
diff --git a/tests/modules/net_address/fixture/main.tf b/tests/modules/net_address/fixture/main.tf
index e716ad1a..4d41b096 100644
--- a/tests/modules/net_address/fixture/main.tf
+++ b/tests/modules/net_address/fixture/main.tf
@@ -15,11 +15,10 @@
*/
module "test" {
- source = "../../../../modules/net-address"
- external_addresses = var.external_addresses
- global_addresses = var.global_addresses
- internal_addresses = var.internal_addresses
- internal_addresses_config = var.internal_addresses_config
- psa_addresses = var.psa_addresses
- project_id = var.project_id
+ source = "../../../../modules/net-address"
+ external_addresses = var.external_addresses
+ global_addresses = var.global_addresses
+ internal_addresses = var.internal_addresses
+ psa_addresses = var.psa_addresses
+ project_id = var.project_id
}
diff --git a/tests/modules/net_address/fixture/variables.tf b/tests/modules/net_address/fixture/variables.tf
index d8272803..ebc90814 100644
--- a/tests/modules/net_address/fixture/variables.tf
+++ b/tests/modules/net_address/fixture/variables.tf
@@ -15,29 +15,17 @@
*/
variable "external_addresses" {
- type = map(string)
+ type = any
default = {}
}
variable "global_addresses" {
- type = list(string)
+ type = any
default = []
}
variable "internal_addresses" {
- type = map(object({
- region = string
- subnetwork = string
- }))
- default = {}
-}
-
-variable "internal_addresses_config" {
- type = map(object({
- address = string
- purpose = string
- tier = string
- }))
+ type = any
default = {}
}
@@ -47,10 +35,6 @@ variable "project_id" {
}
variable "psa_addresses" {
- type = map(object({
- address = string
- network = string
- prefix_length = number
- }))
+ type = any
default = {}
}
diff --git a/tests/modules/net_address/test_plan.py b/tests/modules/net_address/test_plan.py
index 4aa03d27..2274da6f 100644
--- a/tests/modules/net_address/test_plan.py
+++ b/tests/modules/net_address/test_plan.py
@@ -12,14 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
def test_external_addresses(plan_runner):
addresses = '{one = "europe-west1", two = "europe-west2"}'
_, resources = plan_runner(external_addresses=addresses)
assert [r['values']['name'] for r in resources] == ['one', 'two']
- assert set(r['values']['address_type']
- for r in resources) == set(['EXTERNAL'])
- assert [r['values']['region']
- for r in resources] == ['europe-west1', 'europe-west2']
+ assert set(r['values']['address_type'] for r in resources) == set(
+ ['EXTERNAL'])
+ assert [r['values']['region'] for r in resources
+ ] == ['europe-west1', 'europe-west2']
def test_global_addresses(plan_runner):
@@ -29,42 +30,37 @@ def test_global_addresses(plan_runner):
def test_internal_addresses(plan_runner):
- addresses = (
- '{one = {region = "europe-west1", subnetwork = "foobar"}, '
- 'two = {region = "europe-west2", subnetwork = "foobarz"}}'
- )
+ addresses = ('{one = {region = "europe-west1", subnetwork = "foobar"}, '
+ 'two = {region = "europe-west2", subnetwork = "foobarz"}}')
_, resources = plan_runner(internal_addresses=addresses)
assert [r['values']['name'] for r in resources] == ['one', 'two']
- assert set(r['values']['address_type']
- for r in resources) == set(['INTERNAL'])
- assert [r['values']['region']
- for r in resources] == ['europe-west1', 'europe-west2']
+ assert set(r['values']['address_type'] for r in resources) == set(
+ ['INTERNAL'])
+ assert [r['values']['region'] for r in resources
+ ] == ['europe-west1', 'europe-west2']
def test_internal_addresses_config(plan_runner):
- addresses = (
- '{one = {region = "europe-west1", subnetwork = "foobar"}, '
- 'two = {region = "europe-west2", subnetwork = "foobarz"}}'
- )
- config = (
- '{one = {address = "10.0.0.2", purpose = "SHARED_LOADBALANCER_VIP", '
- 'tier=null}}'
- )
- _, resources = plan_runner(internal_addresses=addresses,
- internal_addresses_config=config)
+ addresses = '''{
+ one = {
+ region = "europe-west1"
+ subnetwork = "foobar"
+ address = "10.0.0.2"
+ purpose = "SHARED_LOADBALANCER_VIP"
+ },
+ two = {region = "europe-west2", subnetwork = "foobarz"}
+ }'''
+ _, resources = plan_runner(internal_addresses=addresses)
assert [r['values']['name'] for r in resources] == ['one', 'two']
- assert set(r['values']['address_type']
- for r in resources) == set(['INTERNAL'])
- assert [r['values'].get('address')
- for r in resources] == ['10.0.0.2', None]
- assert [r['values'].get('purpose')
- for r in resources] == ['SHARED_LOADBALANCER_VIP', None]
+ assert set(r['values']['address_type'] for r in resources) == set(
+ ['INTERNAL'])
+ assert [r['values'].get('address') for r in resources] == ['10.0.0.2', None]
+ assert [r['values'].get('purpose') for r in resources
+ ] == ['SHARED_LOADBALANCER_VIP', None]
def test_psa_config(plan_runner):
psa_addresses = '{cloudsql-mysql={address="10.199.0.0", network="foobar", prefix_length = 24}}'
_, resources = plan_runner(psa_addresses=psa_addresses)
- assert set(r['values']['purpose']
- for r in resources) == set(['VPC_PEERING'])
- assert set(r['values']['address']
- for r in resources) == set(['10.199.0.0'])
+ assert set(r['values']['purpose'] for r in resources) == set(['VPC_PEERING'])
+ assert set(r['values']['address'] for r in resources) == set(['10.199.0.0'])
diff --git a/tests/modules/net_ilb_l7/fixture/variables.tf b/tests/modules/net_ilb_l7/fixture/variables.tf
index 0e40c5c0..d513a2a4 100644
--- a/tests/modules/net_ilb_l7/fixture/variables.tf
+++ b/tests/modules/net_ilb_l7/fixture/variables.tf
@@ -88,10 +88,11 @@ variable "backend_services_config" {
variable "forwarding_rule_config" {
description = "Forwarding rule configurations."
type = object({
- ip_version = string
- labels = map(string)
- network_tier = string
- port_range = string
+ ip_version = string
+ labels = map(string)
+ network_tier = string
+ port_range = string
+ service_label = string
})
default = {
allow_global_access = true
@@ -99,7 +100,8 @@ variable "forwarding_rule_config" {
labels = {}
network_tier = "PREMIUM"
# If not specified, 443 if var.https = true; 80 otherwise
- port_range = null
+ port_range = null
+ service_label = null
}
}
diff --git a/tools/state_iam.py b/tools/state_iam.py
index a428f782..1ea887f8 100755
--- a/tools/state_iam.py
+++ b/tools/state_iam.py
@@ -92,11 +92,22 @@ def get_bindings(resources, prefix=None, folders=None):
def get_folders(resources):
'Parse resources and return folder id, name tuples.'
+ folders = {}
for r in resources:
if r['type'] != 'google_folder':
continue
for i in r['instances']:
- yield i['attributes']['id'], i['attributes']['display_name']
+ folder_id = i['attributes']['id']
+ folder_name = i['attributes']['display_name']
+ if folder_name not in folders:
+ folders[folder_name] = []
+ folders[folder_name].append(folder_id)
+ for name, ids in folders.items():
+ for i, folder_id in enumerate(ids):
+ if len(ids) == 1:
+ yield folder_id, name
+ else:
+ yield folder_id, f'{name} [#{i}]'
def output_csv(bindings):
@@ -113,7 +124,8 @@ def output_principals(bindings):
print('# IAM bindings reference')
print('\nLegend: +
additive, •
conditional.')
for resource, resource_groups in resource_grouper:
- print(f'\n## {resource[0].title()} {resource[1].lower()}\n')
+ resource_type, resource_name = resource
+ print(f'\n## {resource_type.title()} {resource_name.lower()}\n')
principal_grouper = itertools.groupby(
resource_groups, key=lambda b: (b.member_type, b.member_id))
print('| members | roles |')